@@ -2635,19 +2635,30 @@ SpecificCall IntrinsicProcTable::Implementation::HandleNull(
2635
2635
static const char *const keywords[]{" mold" , nullptr };
2636
2636
if (CheckAndRearrangeArguments (arguments, context.messages (), keywords, 1 ) &&
2637
2637
arguments[0 ]) {
2638
- if (Expr<SomeType> * mold{arguments[0 ]->UnwrapExpr ()}) {
2639
- bool isProcPtrTarget{IsProcedurePointerTarget (*mold)};
2638
+ Expr<SomeType> *mold{arguments[0 ]->UnwrapExpr ()};
2639
+ bool isBareNull{IsBareNullPointer (mold)};
2640
+ if (isBareNull) {
2641
+ // NULL(NULL()), NULL(NULL(NULL())), &c. are all just NULL()
2642
+ mold = nullptr ;
2643
+ }
2644
+ if (mold) {
2645
+ bool isProcPtrTarget{
2646
+ IsProcedurePointerTarget (*mold) && !IsNullObjectPointer (*mold)};
2640
2647
if (isProcPtrTarget || IsAllocatableOrPointerObject (*mold)) {
2641
2648
characteristics::DummyArguments args;
2642
2649
std::optional<characteristics::FunctionResult> fResult ;
2643
2650
if (isProcPtrTarget) {
2644
2651
// MOLD= procedure pointer
2645
- const Symbol *last{GetLastSymbol (*mold)};
2646
- CHECK (last);
2647
- auto procPointer{IsProcedure (*last)
2648
- ? characteristics::Procedure::Characterize (*last, context)
2649
- : std::nullopt};
2650
- // procPointer is null if there was an error with the analysis
2652
+ std::optional<characteristics::Procedure> procPointer;
2653
+ if (IsNullProcedurePointer (*mold)) {
2654
+ procPointer =
2655
+ characteristics::Procedure::Characterize (*mold, context);
2656
+ } else {
2657
+ const Symbol *last{GetLastSymbol (*mold)};
2658
+ procPointer =
2659
+ characteristics::Procedure::Characterize (DEREF (last), context);
2660
+ }
2661
+ // procPointer is vacant if there was an error with the analysis
2651
2662
// associated with the procedure pointer
2652
2663
if (procPointer) {
2653
2664
args.emplace_back (" mold" s,
@@ -2676,8 +2687,10 @@ SpecificCall IntrinsicProcTable::Implementation::HandleNull(
2676
2687
}
2677
2688
}
2678
2689
}
2679
- context.messages ().Say (arguments[0 ]->sourceLocation (),
2680
- " MOLD= argument to NULL() must be a pointer or allocatable" _err_en_US);
2690
+ if (!isBareNull) {
2691
+ context.messages ().Say (arguments[0 ]->sourceLocation (),
2692
+ " MOLD= argument to NULL() must be a pointer or allocatable" _err_en_US);
2693
+ }
2681
2694
}
2682
2695
characteristics::Procedure::Attrs attrs;
2683
2696
attrs.set (characteristics::Procedure::Attr::NullPointer);
0 commit comments