diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -165,6 +165,8 @@ - Diagnostics relating to macros on the command line of a preprocessed assembly file are now reported as coming from the file ```` instead of ````. +- Clang constexpr evaluator now provides a more concise diagnostic when calling + function pointer that is known to be null. Bug Fixes in This Version ------------------------- diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/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< + "'%0' evaluates to a null function pointer">; def note_constexpr_function_param_value_unknown : Note< "function parameter %0 with unknown value cannot be used in a constant " "expression">; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/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(Callee); + return false; + } FD = dyn_cast_or_null( CalleeLV.getLValueBase().dyn_cast()); if (!FD) diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/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 {{'F' evaluates to a null function pointer}} static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");