Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/DiagnosticASTKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ let Component = "AST" in {
// 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|%select{this conversion|cast that"
" performs the conversions of a reinterpret_cast}1|cast from %1}0"
"%enum_select<ConstexprInvalidCastKind>{%Reinterpret{reinterpret_cast}|%Dynamic{dynamic_cast}|"
"%ThisConversionOrReinterpret{%select{this conversion|cast that performs the conversions "
"of a reinterpret_cast}1}|%CastFrom{cast from %1}}0"
" is not allowed in a constant expression"
"%select{| in C++ standards before C++20||}0">;
def note_constexpr_invalid_void_star_cast : Note<
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2366,12 +2366,14 @@ static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
} else if (!S.getLangOpts().CPlusPlus26) {
const SourceInfo &E = S.Current->getSource(OpPC);
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 3 << "'void *'" << S.Current->getRange(OpPC);
<< diag::ConstexprInvalidCastKind::CastFrom << "'void *'"
<< S.Current->getRange(OpPC);
}
} else {
const SourceInfo &E = S.Current->getSource(OpPC);
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
}

return true;
Expand Down Expand Up @@ -2736,7 +2738,8 @@ inline bool GetIntPtr(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {

if (Desc)
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
<< 2 << S.getLangOpts().CPlusPlus;
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< S.getLangOpts().CPlusPlus;

S.Stk.push<Pointer>(static_cast<uint64_t>(IntVal), Desc);
return true;
Expand Down
24 changes: 16 additions & 8 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8103,12 +8103,14 @@ class ExprEvaluatorBase
}

bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< diag::ConstexprInvalidCastKind::Reinterpret;
return static_cast<Derived*>(this)->VisitCastExpr(E);
}
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
if (!Info.Ctx.getLangOpts().CPlusPlus20)
CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< diag::ConstexprInvalidCastKind::Dynamic;
return static_cast<Derived*>(this)->VisitCastExpr(E);
}
bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E) {
Expand Down Expand Up @@ -8833,7 +8835,8 @@ class LValueExprEvaluator

case CK_LValueBitCast:
this->CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << Info.Ctx.getLangOpts().CPlusPlus;
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< Info.Ctx.getLangOpts().CPlusPlus;
if (!Visit(E->getSubExpr()))
return false;
Result.Designator.setInvalid();
Expand Down Expand Up @@ -9670,10 +9673,12 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
<< E->getType()->getPointeeType();
else
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 3 << SubExpr->getType();
<< diag::ConstexprInvalidCastKind::CastFrom
<< SubExpr->getType();
} else
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << Info.Ctx.getLangOpts().CPlusPlus;
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< Info.Ctx.getLangOpts().CPlusPlus;
Result.Designator.setInvalid();
}
}
Expand Down Expand Up @@ -9712,7 +9717,8 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {

case CK_IntegralToPointer: {
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << Info.Ctx.getLangOpts().CPlusPlus;
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< Info.Ctx.getLangOpts().CPlusPlus;

APValue Value;
if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
Expand Down Expand Up @@ -11177,7 +11183,8 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) {
// Give up if the input isn't an int, float, or vector. For example, we
// reject "(v4i16)(intptr_t)&a".
Info.FFDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << Info.Ctx.getLangOpts().CPlusPlus;
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< Info.Ctx.getLangOpts().CPlusPlus;
return false;
}

Expand Down Expand Up @@ -15196,7 +15203,8 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {

case CK_PointerToIntegral: {
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << Info.Ctx.getLangOpts().CPlusPlus << E->getSourceRange();
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
<< Info.Ctx.getLangOpts().CPlusPlus << E->getSourceRange();

LValue LV;
if (!EvaluatePointer(SubExpr, LV, Info))
Expand Down