[clang] [clang][Sema] Add diagnostic note for reference of function-like macros requiring without parentheses (PR #123495)

via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 9 06:54:01 PST 2025


https://github.com/StarOne01 updated https://github.com/llvm/llvm-project/pull/123495

>From ea6c9ca9cffbf4327fc7bab85e37e2a3c2c0f0cd Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Sun, 19 Jan 2025 07:28:24 +0530
Subject: [PATCH 1/8] [clang][Sema] Add diagnostic note for function-like
 macros requiring parentheses

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 clang/lib/Sema/SemaExpr.cpp                      | 15 ++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bcae9e9f3009387..d9c8fcc66acf280 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5961,6 +5961,8 @@ def err_fold_expression_limit_exceeded: Error<
   "instantiating fold expression with %0 arguments exceeded expression nesting "
   "limit of %1">, DefaultFatal, NoSFINAE;
 
+def note_function_like_macro_requires_parens : Note<
+  "'%0' exists, but as a function-like macro; perhaps, did you forget the parentheses?">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3cd4010740d1944..dff03ac31ef2aa6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2522,6 +2522,19 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
     DC = DC->getLookupParent();
   }
 
+  // Check whether a similar function-like macro exists and suggest it
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+    if (II->hasMacroDefinition()) {
+      MacroInfo *MI = PP.getMacroInfo(II);
+      if (MI && MI->isFunctionLike()) {
+        Diag( R.getNameLoc() ,diag::err_undeclared_var_use) << II->getName();
+        Diag(MI->getDefinitionLoc(), diag::note_function_like_macro_requires_parens)
+            << II->getName();
+        return true;
+      }
+    }
+  }
+
   // We didn't find anything, so try to correct for a typo.
   TypoCorrection Corrected;
   if (S && Out) {
@@ -2632,7 +2645,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
       << SS.getRange();
     return true;
   }
-
+  
   // Give up, we can't recover.
   Diag(R.getNameLoc(), diagnostic) << Name;
   return true;

>From c274178a0ce3a510eaaa9390b277b860bcc5a2a9 Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Sun, 19 Jan 2025 08:30:39 +0530
Subject: [PATCH 2/8] [clang][Tests] Modify tests for function-like macros
 according to the new behavior and Format the changes

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td        | 5 +++--
 clang/lib/Sema/SemaExpr.cpp                             | 7 ++++---
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 6 ++++--
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d9c8fcc66acf280..697b92d32524007 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5961,8 +5961,9 @@ def err_fold_expression_limit_exceeded: Error<
   "instantiating fold expression with %0 arguments exceeded expression nesting "
   "limit of %1">, DefaultFatal, NoSFINAE;
 
-def note_function_like_macro_requires_parens : Note<
-  "'%0' exists, but as a function-like macro; perhaps, did you forget the parentheses?">;
+def note_function_like_macro_requires_parens
+    : Note<"'%0' exists, but as a function-like macro; perhaps, did you forget "
+           "the parentheses?">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index dff03ac31ef2aa6..da894dd3a6d6a6c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2527,8 +2527,9 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
     if (II->hasMacroDefinition()) {
       MacroInfo *MI = PP.getMacroInfo(II);
       if (MI && MI->isFunctionLike()) {
-        Diag( R.getNameLoc() ,diag::err_undeclared_var_use) << II->getName();
-        Diag(MI->getDefinitionLoc(), diag::note_function_like_macro_requires_parens)
+        Diag(R.getNameLoc(), diag::err_undeclared_var_use) << II->getName();
+        Diag(MI->getDefinitionLoc(),
+             diag::note_function_like_macro_requires_parens)
             << II->getName();
         return true;
       }
@@ -2645,7 +2646,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
       << SS.getRange();
     return true;
   }
-  
+
   // Give up, we can't recover.
   Diag(R.getNameLoc(), diagnostic) << Name;
   return true;
diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index 40f53164b263d91..cc7dae0b5a3e00c 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,6 +134,7 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{defined here}}
+// expected-note at -1 2{{'INIT' exists, but as a function-like macro; perhaps, did you forget the parentheses?}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -159,12 +160,13 @@ void test() {
   // expected-note at -3 {{cannot use initializer list at the beginning of a macro argument}}
 }
 
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:11-146:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:23-146:23}:")"
 
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note at -2 2{{defined here}}
+// expected-note at -3 {{'M' exists, but as a function-like macro; perhaps, did you forget the parentheses?}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());

>From 33e001ee6e852f630fd1b69bea424c6e7166078b Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Mon, 20 Jan 2025 13:34:48 +0530
Subject: [PATCH 3/8] Change the note for reference of function-like macros
 requiring without parentheses

Co-authored-by: Sirraide <aeternalmail at gmail.com>
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 697b92d32524007..6d3a065077d4bcf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5962,8 +5962,7 @@ def err_fold_expression_limit_exceeded: Error<
   "limit of %1">, DefaultFatal, NoSFINAE;
 
 def note_function_like_macro_requires_parens
-    : Note<"'%0' exists, but as a function-like macro; perhaps, did you forget "
-           "the parentheses?">;
+    : Note<"'%0' is defined here as a function-like macro; did you mean to write '%0(...)'">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<

>From 5aa4654ffe3f7499faf6f8abc7dbdf3468a8dcb9 Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Tue, 21 Jan 2025 16:20:10 +0530
Subject: [PATCH 4/8] [clang][Tests] Update diagnostic tests for function-like
 macros to clarify usage and improve error messages

---
 .../Preprocessor/macro_with_initializer_list.cpp   | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index cc7dae0b5a3e00c..f7f645cce1180fc 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -133,8 +133,8 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:9-110:9}:"("
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
-#define INIT(var, init) Foo var = init; // expected-note 3{{defined here}}
-// expected-note at -1 2{{'INIT' exists, but as a function-like macro; perhaps, did you forget the parentheses?}}
+#define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' defined here}}
+// expected-note at -1 2{{'INIT' is defined here as a function-like macro; did you mean to write 'INIT(...)'}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -166,7 +166,7 @@ void test() {
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note at -2 2{{defined here}}
-// expected-note at -3 {{'M' exists, but as a function-like macro; perhaps, did you forget the parentheses?}}
+// expected-note at -3 {{'M' is defined here as a function-like macro; did you mean to write 'M(...)'}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -182,3 +182,11 @@ void test2() {
   // expected-error at -3 {{use of undeclared identifier}}
   // expected-note at -4 {{cannot use initializer list at the beginning of a macro argument}}
 }
+
+#define LIM() 10 
+// expected-note at -1 {{'LIM' is defined here as a function-like macro; did you mean to write 'LIM(...)'}}
+
+void test3() {
+  int iter = LIM;
+  // expected-error at -1 {{use of undeclared identifier LIM}}
+}
\ No newline at end of file

>From bd0848786ffb70e6f06b2b93b1b2fae46478484c Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Tue, 21 Jan 2025 16:22:39 +0530
Subject: [PATCH 5/8] Change the note for reference of function-like macros
 requiring without parentheses

Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva at intel.com>
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6d3a065077d4bcf..34ed18e518773e4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5962,7 +5962,7 @@ def err_fold_expression_limit_exceeded: Error<
   "limit of %1">, DefaultFatal, NoSFINAE;
 
 def note_function_like_macro_requires_parens
-    : Note<"'%0' is defined here as a function-like macro; did you mean to write '%0(...)'">;
+    : Note<"'%0' is defined here as a function-like macro; did you mean '%0(...)'">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<

>From 6ef338ab4c2dd123397327fb3de7f1057643fa49 Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Tue, 21 Jan 2025 17:03:21 +0530
Subject: [PATCH 6/8] [clang][Tests] Update diagnostic tests for function-like
 macros for the updated note

---
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index f7f645cce1180fc..cf1d137eadcbe2f 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,7 +134,7 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' defined here}}
-// expected-note at -1 2{{'INIT' is defined here as a function-like macro; did you mean to write 'INIT(...)'}}
+// expected-note at -1 2{{'INIT' is defined here as a function-like macro; did you mean 'INIT(...)'}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -166,7 +166,7 @@ void test() {
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note at -2 2{{defined here}}
-// expected-note at -3 {{'M' is defined here as a function-like macro; did you mean to write 'M(...)'}}
+// expected-note at -3 {{'M' is defined here as a function-like macro; did you mean 'M(...)'}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -184,7 +184,7 @@ void test2() {
 }
 
 #define LIM() 10 
-// expected-note at -1 {{'LIM' is defined here as a function-like macro; did you mean to write 'LIM(...)'}}
+// expected-note at -1 {{'LIM' is defined here as a function-like macro; did you mean 'LIM(...)'}}
 
 void test3() {
   int iter = LIM;

>From 094887dbe3a521ad4733cd37cbfb5313bbb0dc4e Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Sun, 9 Feb 2025 14:20:36 +0530
Subject: [PATCH 7/8] [clang][Sema] Improve diagnostics for undeclared
 function-like macros

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  4 +-
 clang/lib/Sema/SemaExpr.cpp                   | 43 ++++++++++++-------
 .../macro_with_initializer_list.cpp           | 14 +-----
 clang/test/Sema/typo-correction.c             | 22 ++++++++++
 4 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 34ed18e518773e4..33a3bfe4ff6468d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5962,7 +5962,7 @@ def err_fold_expression_limit_exceeded: Error<
   "limit of %1">, DefaultFatal, NoSFINAE;
 
 def note_function_like_macro_requires_parens
-    : Note<"'%0' is defined here as a function-like macro; did you mean '%0(...)'">;
+    : Note<"'%0' defined here as a function-like macro">;
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<
@@ -10857,6 +10857,8 @@ def err_undeclared_use_suggest : Error<
   "use of undeclared %0; did you mean %1?">;
 def err_undeclared_var_use_suggest : Error<
   "use of undeclared identifier %0; did you mean %1?">;
+def err_undeclared_var_use_suggest_func_like_macro
+    : Error<"use of undeclared identifier %0; did you mean %0(...)?">;
 def err_no_template : Error<"no template named %0">;
 def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
 def err_no_member_template : Error<"no template named %0 in %1">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index da894dd3a6d6a6c..27c2cf65762e3de 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2347,6 +2347,27 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
   return E;
 }
 
+// Check whether a similar function-like macro exists and suggest it
+static bool isFunctionLikeMacro(const DeclarationName &Name, Sema &SemaRef,
+                                const SourceLocation &TypoLoc) {
+
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+    if (II->hasMacroDefinition()) {
+      MacroInfo *MI = SemaRef.PP.getMacroInfo(II);
+      if (MI && MI->isFunctionLike()) {
+        SemaRef.Diag(TypoLoc,
+                     diag::err_undeclared_var_use_suggest_func_like_macro)
+            << II->getName();
+        SemaRef.Diag(MI->getDefinitionLoc(),
+                     diag::note_function_like_macro_requires_parens)
+            << II->getName();
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 void
 Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
                              TemplateArgumentListInfo &Buffer,
@@ -2382,8 +2403,11 @@ static void emitEmptyLookupTypoDiagnostic(
     if (Ctx)
       SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx
                                                  << SS.getRange();
-    else
+    else {
+      if (isFunctionLikeMacro(Typo, SemaRef, TypoLoc))
+        return;
       SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;
+    }
     return;
   }
 
@@ -2522,20 +2546,6 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
     DC = DC->getLookupParent();
   }
 
-  // Check whether a similar function-like macro exists and suggest it
-  if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
-    if (II->hasMacroDefinition()) {
-      MacroInfo *MI = PP.getMacroInfo(II);
-      if (MI && MI->isFunctionLike()) {
-        Diag(R.getNameLoc(), diag::err_undeclared_var_use) << II->getName();
-        Diag(MI->getDefinitionLoc(),
-             diag::note_function_like_macro_requires_parens)
-            << II->getName();
-        return true;
-      }
-    }
-  }
-
   // We didn't find anything, so try to correct for a typo.
   TypoCorrection Corrected;
   if (S && Out) {
@@ -2638,6 +2648,9 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
   }
   R.clear();
 
+  if (isFunctionLikeMacro(Name, SemaRef, R.getNameLoc()))
+    return true;
+
   // Emit a special diagnostic for failed member lookups.
   // FIXME: computing the declaration context might fail here (?)
   if (!SS.isEmpty()) {
diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index cf1d137eadcbe2f..5f66971622ce728 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,7 +134,6 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' defined here}}
-// expected-note at -1 2{{'INIT' is defined here as a function-like macro; did you mean 'INIT(...)'}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -160,13 +159,12 @@ void test() {
   // expected-note at -3 {{cannot use initializer list at the beginning of a macro argument}}
 }
 
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:11-146:11}:"("
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:23-146:23}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
 
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note at -2 2{{defined here}}
-// expected-note at -3 {{'M' is defined here as a function-like macro; did you mean 'M(...)'}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -181,12 +179,4 @@ void test2() {
   // expected-error at -2 {{too many arguments provided}}
   // expected-error at -3 {{use of undeclared identifier}}
   // expected-note at -4 {{cannot use initializer list at the beginning of a macro argument}}
-}
-
-#define LIM() 10 
-// expected-note at -1 {{'LIM' is defined here as a function-like macro; did you mean 'LIM(...)'}}
-
-void test3() {
-  int iter = LIM;
-  // expected-error at -1 {{use of undeclared identifier LIM}}
 }
\ No newline at end of file
diff --git a/clang/test/Sema/typo-correction.c b/clang/test/Sema/typo-correction.c
index 4157207a9ac4279..3efd35538dd585b 100644
--- a/clang/test/Sema/typo-correction.c
+++ b/clang/test/Sema/typo-correction.c
@@ -114,3 +114,25 @@ void PR40286_3(int the_value) {
 void PR40286_4(int the_value) { // expected-note {{'the_value' declared here}}
   PR40286_h(the_value, the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'; did you mean 'the_value'?}}
 }
+
+#define FOO1() 10
+// expected-note at -1 4 {{'FOO1' defined here as a function-like macro}}
+
+int x = FOO1; // expected-error {{use of undeclared identifier FOO1; did you mean FOO1(...)?}}
+
+void test3() {
+  int iter = FOO1;
+  // expected-error at -1 {{use of undeclared identifier FOO1; did you mean FOO1(...)?}}
+}
+
+void bar(int);
+
+void test4() {
+    int FOO; // expected-note {{'FOO' declared here}}
+    int x = FOO1; // expected-error {{use of undeclared identifier 'FOO1'; did you mean 'FOO'?}}
+}
+
+void test5() {
+    FOO1 + 1; // expected-error {{use of undeclared identifier FOO1; did you mean FOO1(...)?}}
+    bar(FOO1); // expected-error {{use of undeclared identifier FOO1; did you mean FOO1(...)?}}
+}

>From eac145ae3c3de06573cc7cbef40fe5436606e089 Mon Sep 17 00:00:00 2001
From: Prashanth <TheStarOne01 at proton.me>
Date: Sun, 9 Feb 2025 14:50:49 +0530
Subject: [PATCH 8/8] [clang][Tests] Enhance diagnostic notes for function-like
 macros in initializer list tests

---
 clang/test/Preprocessor/macro_with_initializer_list.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp b/clang/test/Preprocessor/macro_with_initializer_list.cpp
index 5f66971622ce728..dab60e60b14a186 100644
--- a/clang/test/Preprocessor/macro_with_initializer_list.cpp
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -134,6 +134,7 @@ void test_NE() {
 // CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
 
 #define INIT(var, init) Foo var = init; // expected-note 3{{macro 'INIT' defined here}}
+// expected-note at -1 2{{'INIT' defined here as a function-like macro}}
 // Can't use an initializer list as a macro argument.  The commas in the list
 // will be interpretted as argument separaters and adding parenthesis will
 // make it no longer an initializer list.
@@ -159,12 +160,13 @@ void test() {
   // expected-note at -3 {{cannot use initializer list at the beginning of a macro argument}}
 }
 
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
-// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:11-146:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{146:23-146:23}:")"
 
 #define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
   Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
 // expected-note at -2 2{{defined here}}
+// expected-note at -3 {{'M' defined here as a function-like macro}}
 void test2() {
   M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
         Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
@@ -179,4 +181,4 @@ void test2() {
   // expected-error at -2 {{too many arguments provided}}
   // expected-error at -3 {{use of undeclared identifier}}
   // expected-note at -4 {{cannot use initializer list at the beginning of a macro argument}}
-}
\ No newline at end of file
+}



More information about the cfe-commits mailing list