[PATCH] D145793: [clang][AST] Improve diagnostic for `nullptr` constexpr function pointer call

Takuya Shimizu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 10 07:18:31 PST 2023


hazohelet created this revision.
hazohelet added reviewers: tbaeder, cjdb, aaron.ballman.
Herald added a project: All.
hazohelet requested review of this revision.
Herald added a project: clang.

This patch improves diagnostic for clang constexpr evaluator by adding a check for `nullptr` in function pointer call evaluations.
This fixes https://github.com/llvm/llvm-project/issues/59872

ex.

  constexpr int foo(int (*bla)(void)) {
    return bla();
  }
  
  static_assert(foo(nullptr) == 1);

BEFORE this patch, clang generates the following diagnostic for the code above

  <source>:5:15: error: static assertion expression is not an integral constant expression
  static_assert(foo(nullptr) == 1);
                ^~~~~~~~~~~~~~~~~
  <source>:2:10: note: subexpression not valid in a constant expression
    return bla();
           ^
  <source>:5:15: note: in call to 'foo(nullptr)'
  static_assert(foo(nullptr) == 1);
                ^
  1 error generated.

AFTER this patch, `subexpression not valid in a constant expression` note is replaced with `function pointer 'bla' evaluates to a null pointer`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145793

Files:
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp


Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===================================================================
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -279,7 +279,7 @@
   constexpr auto Select(int n) -> int (*)(int) {
     return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0;
   }
-  constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{subexpression}}
+  constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{function pointer 'F' evaluates to a null pointer}}
 
   static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");
 
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -7668,6 +7668,11 @@
 
       if (!CalleeLV.getLValueOffset().isZero())
         return Error(Callee);
+      if (CalleeLV.isNullPointer()) {
+        Info.FFDiag(Callee, diag::note_constexpr_null_callee)
+            << const_cast<Expr *>(Callee);
+        return false;
+      }
       FD = dyn_cast_or_null<FunctionDecl>(
           CalleeLV.getLValueBase().dyn_cast<const ValueDecl *>());
       if (!FD)
Index: clang/include/clang/Basic/DiagnosticASTKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticASTKinds.td
+++ clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -127,6 +127,8 @@
   "access array element of|perform pointer arithmetic on|"
   "access real component of|"
   "access imaginary component of}0 null pointer">;
+def note_constexpr_null_callee : Note<
+  "function pointer '%0' evaluates to a null pointer">;
 def note_constexpr_function_param_value_unknown : Note<
   "function parameter %0 with unknown value cannot be used in a constant "
   "expression">;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D145793.504136.patch
Type: text/x-patch
Size: 1913 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230310/383cc372/attachment.bin>


More information about the cfe-commits mailing list