diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -136,6 +136,8 @@ - no_sanitize("...") on a global variable for known but not relevant sanitizers is now just a warning. It now says that this will be ignored instead of incorrectly saying no_sanitize only applies to functions and methods. +- No longer mention ``reinterpet_cast`` in the invalid constant expression + diagnostic note when in C mode. Non-comprehensive list of changes in this release ------------------------------------------------- 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 @@ -11,8 +11,9 @@ // Constant expression diagnostics. These (and their users) belong in Sema. def note_expr_divide_by_zero : Note<"division by zero">; def note_constexpr_invalid_cast : Note< - "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of" - " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression" + "%select{reinterpret_cast|dynamic_cast|%select{this conversion|cast that" + " performs the conversions of a reinterpret_cast}1|cast from %1}0" + " is not allowed in a constant expression" "%select{| in C++ standards before C++20||}0">; def note_constexpr_invalid_downcast : Note< "cannot cast object of dynamic type %0 to type %1">; 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 @@ -8178,7 +8178,8 @@ return LValueExprEvaluatorBaseTy::VisitCastExpr(E); case CK_LValueBitCast: - this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2; + this->CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << Info.Ctx.getLangOpts().CPlusPlus; if (!Visit(E->getSubExpr())) return false; Result.Designator.setInvalid(); @@ -8889,9 +8890,10 @@ Result.Designator.setInvalid(); if (SubExpr->getType()->isVoidPointerType()) CCEDiag(E, diag::note_constexpr_invalid_cast) - << 3 << SubExpr->getType(); + << 3 << SubExpr->getType(); else - CCEDiag(E, diag::note_constexpr_invalid_cast) << 2; + CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << Info.Ctx.getLangOpts().CPlusPlus; } } if (E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr) @@ -8928,7 +8930,8 @@ return ZeroInitialization(E); case CK_IntegralToPointer: { - CCEDiag(E, diag::note_constexpr_invalid_cast) << 2; + CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << Info.Ctx.getLangOpts().CPlusPlus; APValue Value; if (!EvaluateIntegerOrLValue(SubExpr, Value, Info)) @@ -13587,7 +13590,8 @@ } case CK_PointerToIntegral: { - CCEDiag(E, diag::note_constexpr_invalid_cast) << 2; + CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << Info.Ctx.getLangOpts().CPlusPlus; LValue LV; if (!EvaluatePointer(SubExpr, LV, Info)) diff --git a/clang/test/Sema/cast.c b/clang/test/Sema/cast.c --- a/clang/test/Sema/cast.c +++ b/clang/test/Sema/cast.c @@ -1,4 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown %s -verify +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown %s -verify -Wvla + +int array[(long)(char *)0]; // expected-warning {{variable length array used}} \ + // expected-warning {{variable length array folded to constant array as an extension}} \ + // expected-note {{this conversion is not allowed in a constant expression}} typedef struct { unsigned long bits[(((1) + (64) - 1) / (64))]; } cpumask_t; cpumask_t x; 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 @@ -11,6 +11,10 @@ } +int array[(long)(char *)0]; // expected-warning {{variable length arrays are a C99 feature}} \ + // expected-warning {{variable length array folded to constant array as an extension}} \ + // expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + typedef decltype(sizeof(char)) size_t; template constexpr T id(const T &t) { return t; }