- 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
-------------------------------------------------
// 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">;
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();
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)
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))
}
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))
-// 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;
}
+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<typename T> constexpr T id(const T &t) { return t; }