@@ -1243,7 +1243,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1243
1243
if (!arg) {
1244
1244
++missingActualArguments;
1245
1245
} else if (arg->isAlternateReturn ()) {
1246
- messages.Say (
1246
+ messages.Say (arg-> sourceLocation (),
1247
1247
" alternate return specifier not acceptable on call to intrinsic '%s'" _err_en_US,
1248
1248
name);
1249
1249
return std::nullopt;
@@ -1323,7 +1323,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1323
1323
continue ;
1324
1324
}
1325
1325
} else if (d.optionality == Optionality::missing) {
1326
- messages.Say (" unexpected '%s=' argument" _err_en_US, d.keyword );
1326
+ messages.Say (arg->sourceLocation (), " unexpected '%s=' argument" _err_en_US,
1327
+ d.keyword );
1327
1328
return std::nullopt;
1328
1329
}
1329
1330
if (arg->GetAssumedTypeDummy ()) {
@@ -1334,8 +1335,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1334
1335
d.typePattern .kindCode == KindCode::addressable)) {
1335
1336
continue ;
1336
1337
} else {
1337
- messages.Say (" Assumed type TYPE(*) dummy argument not allowed "
1338
- " for '%s=' intrinsic argument" _err_en_US,
1338
+ messages.Say (arg-> sourceLocation (),
1339
+ " Assumed type TYPE(*) dummy argument not allowed for '%s=' intrinsic argument" _err_en_US,
1339
1340
d.keyword );
1340
1341
return std::nullopt;
1341
1342
}
@@ -1352,11 +1353,11 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1352
1353
const IntrinsicDummyArgument *nextParam{
1353
1354
j + 1 < dummies ? &dummy[j + 1 ] : nullptr };
1354
1355
if (nextParam && nextParam->rank == Rank::elementalOrBOZ) {
1355
- messages.Say (
1356
+ messages.Say (arg-> sourceLocation (),
1356
1357
" Typeless (BOZ) not allowed for both '%s=' & '%s=' arguments" _err_en_US, // C7109
1357
1358
d.keyword , nextParam->keyword );
1358
1359
} else {
1359
- messages.Say (
1360
+ messages.Say (arg-> sourceLocation (),
1360
1361
" Typeless (BOZ) not allowed for '%s=' argument" _err_en_US,
1361
1362
d.keyword );
1362
1363
}
@@ -1370,15 +1371,16 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1370
1371
} else if (d.typePattern .kindCode == KindCode::nullPointerType) {
1371
1372
continue ;
1372
1373
} else {
1373
- messages.Say (
1374
+ messages.Say (arg-> sourceLocation (),
1374
1375
" Actual argument for '%s=' may not be a procedure" _err_en_US,
1375
1376
d.keyword );
1376
1377
}
1377
1378
}
1378
1379
return std::nullopt;
1379
1380
} else if (!d.typePattern .categorySet .test (type->category ())) {
1380
- messages.Say (" Actual argument for '%s=' has bad type '%s'" _err_en_US,
1381
- d.keyword , type->AsFortran ());
1381
+ messages.Say (arg->sourceLocation (),
1382
+ " Actual argument for '%s=' has bad type '%s'" _err_en_US, d.keyword ,
1383
+ type->AsFortran ());
1382
1384
return std::nullopt; // argument has invalid type category
1383
1385
}
1384
1386
bool argOk{false };
@@ -1457,7 +1459,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1457
1459
CRASH_NO_CASE;
1458
1460
}
1459
1461
if (!argOk) {
1460
- messages.Say (
1462
+ messages.Say (arg-> sourceLocation (),
1461
1463
" Actual argument for '%s=' has bad type or kind '%s'" _err_en_US,
1462
1464
d.keyword , type->AsFortran ());
1463
1465
return std::nullopt;
@@ -1475,8 +1477,8 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1475
1477
if (const ActualArgument * arg{actualForDummy[j]}) {
1476
1478
bool isAssumedRank{IsAssumedRank (*arg)};
1477
1479
if (isAssumedRank && d.rank != Rank::anyOrAssumedRank) {
1478
- messages.Say (" Assumed-rank array cannot be forwarded to "
1479
- " '%s=' argument" _err_en_US,
1480
+ messages.Say (arg-> sourceLocation (),
1481
+ " Assumed-rank array cannot be forwarded to '%s=' argument" _err_en_US,
1480
1482
d.keyword );
1481
1483
return std::nullopt;
1482
1484
}
@@ -1499,7 +1501,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1499
1501
case Rank::shape:
1500
1502
CHECK (!shapeArgSize);
1501
1503
if (rank != 1 ) {
1502
- messages.Say (
1504
+ messages.Say (arg-> sourceLocation (),
1503
1505
" 'shape=' argument must be an array of rank 1" _err_en_US);
1504
1506
return std::nullopt;
1505
1507
} else {
@@ -1512,7 +1514,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1512
1514
}
1513
1515
}
1514
1516
if (!argOk) {
1515
- messages.Say (
1517
+ messages.Say (arg-> sourceLocation (),
1516
1518
" 'shape=' argument must be a vector of known size" _err_en_US);
1517
1519
return std::nullopt;
1518
1520
}
@@ -1530,7 +1532,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1530
1532
case Rank::coarray:
1531
1533
argOk = IsCoarray (*arg);
1532
1534
if (!argOk) {
1533
- messages.Say (
1535
+ messages.Say (arg-> sourceLocation (),
1534
1536
" 'coarray=' argument must have corank > 0 for intrinsic '%s'" _err_en_US,
1535
1537
name);
1536
1538
return std::nullopt;
@@ -1556,11 +1558,11 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1556
1558
if (std::optional<Shape> shape{GetShape (context, *arg)}) {
1557
1559
if (!shape->empty () && !shape->back ().has_value ()) {
1558
1560
if (strcmp (name, " shape" ) == 0 ) {
1559
- messages.Say (
1561
+ messages.Say (arg-> sourceLocation (),
1560
1562
" The '%s=' argument to the intrinsic function '%s' may not be assumed-size" _err_en_US,
1561
1563
d.keyword , name);
1562
1564
} else {
1563
- messages.Say (
1565
+ messages.Say (arg-> sourceLocation (),
1564
1566
" A dim= argument is required for '%s' when the array is assumed-size" _err_en_US,
1565
1567
name);
1566
1568
}
@@ -1606,8 +1608,9 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
1606
1608
d.keyword , name);
1607
1609
}
1608
1610
if (!argOk) {
1609
- messages.Say (" '%s=' argument has unacceptable rank %d" _err_en_US,
1610
- d.keyword , rank);
1611
+ messages.Say (arg->sourceLocation (),
1612
+ " '%s=' argument has unacceptable rank %d" _err_en_US, d.keyword ,
1613
+ rank);
1611
1614
return std::nullopt;
1612
1615
}
1613
1616
}
@@ -2020,14 +2023,15 @@ bool CheckAndRearrangeArguments(ActualArguments &arguments,
2020
2023
return false ;
2021
2024
}
2022
2025
} else if (anyKeywords) {
2023
- messages.Say (
2026
+ messages.Say (arg ? arg-> sourceLocation () : messages. at (),
2024
2027
" A positional actual argument may not appear after any keyword arguments" _err_en_US);
2025
2028
return false ;
2026
2029
} else {
2027
2030
dummyIndex = position++;
2028
2031
}
2029
2032
if (rearranged[dummyIndex]) {
2030
- messages.Say (" Dummy argument '%s=' appears more than once" _err_en_US,
2033
+ messages.Say (arg ? arg->sourceLocation () : messages.at (),
2034
+ " Dummy argument '%s=' appears more than once" _err_en_US,
2031
2035
dummyKeywords[dummyIndex]);
2032
2036
return false ;
2033
2037
}
@@ -2081,7 +2085,7 @@ SpecificCall IntrinsicProcTable::Implementation::HandleNull(
2081
2085
" mold" s, characteristics::DummyDataObject{typeAndShape});
2082
2086
fResult .emplace (std::move (typeAndShape));
2083
2087
} else {
2084
- context.messages ().Say (
2088
+ context.messages ().Say (arguments[ 0 ]-> sourceLocation (),
2085
2089
" MOLD= argument to NULL() lacks type" _err_en_US);
2086
2090
}
2087
2091
if (goodProcPointer) {
@@ -2095,7 +2099,7 @@ SpecificCall IntrinsicProcTable::Implementation::HandleNull(
2095
2099
}
2096
2100
}
2097
2101
}
2098
- context.messages ().Say (
2102
+ context.messages ().Say (arguments[ 0 ]-> sourceLocation (),
2099
2103
" MOLD= argument to NULL() must be a pointer or allocatable" _err_en_US);
2100
2104
}
2101
2105
characteristics::Procedure::Attrs attrs;
@@ -2121,15 +2125,15 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
2121
2125
CHECK (arguments.size () == 3 );
2122
2126
if (const auto *expr{arguments[0 ].value ().UnwrapExpr ()}) {
2123
2127
if (expr->Rank () > 0 ) {
2124
- context.messages ().Say (
2128
+ context.messages ().Say (arguments[ 0 ]-> sourceLocation (),
2125
2129
" CPTR= argument to C_F_POINTER() must be scalar" _err_en_US);
2126
2130
}
2127
2131
if (auto type{expr->GetType ()}) {
2128
2132
if (type->category () != TypeCategory::Derived ||
2129
2133
type->IsPolymorphic () ||
2130
2134
type->GetDerivedTypeSpec ().typeSymbol ().name () !=
2131
2135
" __builtin_c_ptr" ) {
2132
- context.messages ().Say (
2136
+ context.messages ().Say (arguments[ 0 ]-> sourceLocation (),
2133
2137
" CPTR= argument to C_F_POINTER() must be a C_PTR" _err_en_US);
2134
2138
}
2135
2139
characteristics::DummyDataObject cptr{
@@ -2142,11 +2146,11 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
2142
2146
int fptrRank{expr->Rank ()};
2143
2147
if (auto type{expr->GetType ()}) {
2144
2148
if (type->HasDeferredTypeParameter ()) {
2145
- context.messages ().Say (
2149
+ context.messages ().Say (arguments[ 1 ]-> sourceLocation (),
2146
2150
" FPTR= argument to C_F_POINTER() may not have a deferred type parameter" _err_en_US);
2147
2151
}
2148
2152
if (ExtractCoarrayRef (*expr)) {
2149
- context.messages ().Say (
2153
+ context.messages ().Say (arguments[ 1 ]-> sourceLocation (),
2150
2154
" FPTR= argument to C_F_POINTER() may not be a coindexed object" _err_en_US);
2151
2155
}
2152
2156
characteristics::DummyDataObject fptr{
@@ -2155,11 +2159,11 @@ IntrinsicProcTable::Implementation::HandleC_F_Pointer(
2155
2159
fptr.attrs .set (characteristics::DummyDataObject::Attr::Pointer);
2156
2160
dummies.emplace_back (" fptr" s, std::move (fptr));
2157
2161
} else {
2158
- context.messages ().Say (
2162
+ context.messages ().Say (arguments[ 1 ]-> sourceLocation (),
2159
2163
" FPTR= argument to C_F_POINTER() must have a type" _err_en_US);
2160
2164
}
2161
2165
if (arguments[2 ] && fptrRank == 0 ) {
2162
- context.messages ().Say (
2166
+ context.messages ().Say (arguments[ 2 ]-> sourceLocation (),
2163
2167
" SHAPE= argument to C_F_POINTER() may not appear when FPTR= is scalar" _err_en_US);
2164
2168
} else if (!arguments[2 ] && fptrRank > 0 ) {
2165
2169
context.messages ().Say (
@@ -2196,7 +2200,7 @@ static bool CheckAssociated(SpecificCall &call, FoldingContext &context) {
2196
2200
if (const auto *pointerExpr{pointerArg->UnwrapExpr ()}) {
2197
2201
if (const Symbol * pointerSymbol{GetLastSymbol (*pointerExpr)}) {
2198
2202
if (!pointerSymbol->attrs ().test (semantics::Attr::POINTER)) {
2199
- AttachDeclaration (context.messages ().Say (
2203
+ AttachDeclaration (context.messages ().Say (pointerArg-> sourceLocation (),
2200
2204
" POINTER= argument of ASSOCIATED() must be a "
2201
2205
" POINTER" _err_en_US),
2202
2206
*pointerSymbol);
@@ -2268,6 +2272,7 @@ static bool CheckAssociated(SpecificCall &call, FoldingContext &context) {
2268
2272
CHECK (!symbols.empty ());
2269
2273
if (!GetLastTarget (symbols)) {
2270
2274
parser::Message *msg{context.messages ().Say (
2275
+ targetArg->sourceLocation (),
2271
2276
" TARGET= argument '%s' must have either the POINTER or the TARGET attribute" _err_en_US,
2272
2277
targetExpr->AsFortran ())};
2273
2278
for (SymbolRef ref : symbols) {
@@ -2301,7 +2306,8 @@ static bool ApplySpecificChecks(SpecificCall &call, FoldingContext &context) {
2301
2306
bool ok{true };
2302
2307
const std::string &name{call.specificIntrinsic .name };
2303
2308
if (name == " allocated" ) {
2304
- if (const auto &arg{call.arguments [0 ]}) {
2309
+ const auto &arg{call.arguments [0 ]};
2310
+ if (arg) {
2305
2311
if (const auto *expr{arg->UnwrapExpr ()}) {
2306
2312
if (const Symbol * symbol{GetLastSymbol (*expr)}) {
2307
2313
ok = symbol->attrs ().test (semantics::Attr::ALLOCATABLE);
@@ -2310,20 +2316,23 @@ static bool ApplySpecificChecks(SpecificCall &call, FoldingContext &context) {
2310
2316
}
2311
2317
if (!ok) {
2312
2318
context.messages ().Say (
2319
+ arg ? arg->sourceLocation () : context.messages ().at (),
2313
2320
" Argument of ALLOCATED() must be an ALLOCATABLE object or component" _err_en_US);
2314
2321
}
2315
2322
} else if (name == " associated" ) {
2316
2323
return CheckAssociated (call, context);
2317
2324
} else if (name == " loc" ) {
2318
- if ( const auto &arg{call.arguments [0 ]}) {
2319
- ok = arg-> GetAssumedTypeDummy () || GetLastSymbol (arg-> UnwrapExpr ());
2320
- }
2325
+ const auto &arg{call.arguments [0 ]};
2326
+ ok =
2327
+ arg && (arg-> GetAssumedTypeDummy () || GetLastSymbol (arg-> UnwrapExpr ()));
2321
2328
if (!ok) {
2322
2329
context.messages ().Say (
2330
+ arg ? arg->sourceLocation () : context.messages ().at (),
2323
2331
" Argument of LOC() must be an object or procedure" _err_en_US);
2324
2332
}
2325
2333
} else if (name == " present" ) {
2326
- if (const auto &arg{call.arguments [0 ]}) {
2334
+ const auto &arg{call.arguments [0 ]};
2335
+ if (arg) {
2327
2336
if (const auto *expr{arg->UnwrapExpr ()}) {
2328
2337
if (const Symbol * symbol{UnwrapWholeSymbolDataRef (*expr)}) {
2329
2338
ok = symbol->attrs ().test (semantics::Attr::OPTIONAL);
@@ -2332,6 +2341,7 @@ static bool ApplySpecificChecks(SpecificCall &call, FoldingContext &context) {
2332
2341
}
2333
2342
if (!ok) {
2334
2343
context.messages ().Say (
2344
+ arg ? arg->sourceLocation () : context.messages ().at (),
2335
2345
" Argument of PRESENT() must be the name of an OPTIONAL dummy argument" _err_en_US);
2336
2346
}
2337
2347
}
0 commit comments