Skip to content

Commit 32892b6

Browse files
committed
[clang][ExprConst] Add diagnostics for invalid binary arithmetic
... between unrelated declarations or literals.
1 parent e983420 commit 32892b6

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
@@ -14600,8 +14600,21 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1460014600
return Error(E);
1460114601
const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr *>();
1460214602
const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr *>();
14603-
if (!LHSExpr || !RHSExpr)
14604-
return Error(E);
14603+
if (!LHSExpr || !RHSExpr) {
14604+
std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
14605+
std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
14606+
Info.FFDiag(E, diag::note_constexpr_pointer_arith_unspecified)
14607+
<< LHS << RHS;
14608+
return false;
14609+
}
14610+
14611+
if (ArePotentiallyOverlappingStringLiterals(Info, LHSValue, RHSValue)) {
14612+
std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
14613+
std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
14614+
Info.FFDiag(E, diag::note_constexpr_literal_arith) << LHS << RHS;
14615+
return false;
14616+
}
14617+
1460514618
const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
1460614619
const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
1460714620
if (!LHSAddrExpr || !RHSAddrExpr)

0 commit comments

Comments
 (0)