Skip to content

Commit 0d631c5

Browse files
committed
[clang][ExprConst] Add diagnostics for invalid binary arithmetic
... between unrelated declarations or literals.
1 parent 9fc152d commit 0d631c5

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

clang/include/clang/Basic/DiagnosticASTKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,15 @@ def note_constexpr_pointer_subtraction_zero_size : Note<
9191
"subtraction of pointers to type %0 of zero size">;
9292
def note_constexpr_pointer_comparison_unspecified : Note<
9393
"comparison between '%0' and '%1' has unspecified value">;
94+
def note_constexpr_pointer_arith_unspecified : Note<
95+
"arithmetic involving '%0' and '%1' has unspecified value">;
9496
def note_constexpr_pointer_constant_comparison : Note<
9597
"comparison of numeric address '%0' with pointer '%1' can only be performed "
9698
"at runtime">;
9799
def note_constexpr_literal_comparison : Note<
98100
"comparison of addresses of literals has unspecified value">;
101+
def note_constexpr_literal_arith : Note<
102+
"arithmetic on addresses of literals has unspecified value">;
99103
def note_constexpr_opaque_call_comparison : Note<
100104
"comparison against opaque constant address '%0' can only be performed at "
101105
"runtime">;

clang/lib/AST/ExprConstant.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14588,8 +14588,21 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1458814588
return Error(E);
1458914589
const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr *>();
1459014590
const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr *>();
14591-
if (!LHSExpr || !RHSExpr)
14592-
return Error(E);
14591+
if (!LHSExpr || !RHSExpr) {
14592+
std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
14593+
std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
14594+
Info.FFDiag(E, diag::note_constexpr_pointer_arith_unspecified)
14595+
<< LHS << RHS;
14596+
return false;
14597+
}
14598+
14599+
if (ArePotentiallyOverlappingStringLiterals(Info, LHSValue, RHSValue)) {
14600+
std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
14601+
std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
14602+
Info.FFDiag(E, diag::note_constexpr_literal_arith) << LHS << RHS;
14603+
return false;
14604+
}
14605+
1459314606
const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
1459414607
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
1459514608
if (!LHSAddrExpr || !RHSAddrExpr)

0 commit comments

Comments
 (0)