From: Richard Smith Date: Wed, 11 Jul 2018 00:29:05 +0000 (+0000) Subject: PR38095: Allow constant-folding of loads through bitcasted pointers if X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7e3affb96522e46cd36cc0e774c533f3c7c47b8;p=clang PR38095: Allow constant-folding of loads through bitcasted pointers if the bitcast only changed cvr-qualifications within the pointer type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336746 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 828368a3e1..bf21bc65e2 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -5787,8 +5787,8 @@ bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { return evaluateLValue(E->getSubExpr(), Result); } -bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { - const Expr* SubExpr = E->getSubExpr(); +bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { + const Expr *SubExpr = E->getSubExpr(); switch (E->getCastKind()) { default: @@ -5805,7 +5805,11 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { // permitted in constant expressions in C++11. Bitcasts from cv void* are // also static_casts, but we disallow them as a resolution to DR1312. if (!E->getType()->isVoidPointerType()) { - Result.Designator.setInvalid(); + // If we changed anything other than cvr-qualifiers, we can't use this + // value for constant folding. FIXME: Qualification conversions should + // always be CK_NoOp, but we get this wrong in C. + if (!Info.Ctx.hasCvrSimilarType(E->getType(), E->getSubExpr()->getType())) + Result.Designator.setInvalid(); if (SubExpr->getType()->isVoidPointerType()) CCEDiag(E, diag::note_constexpr_invalid_cast) << 3 << SubExpr->getType(); diff --git a/test/Sema/diagnose_if.c b/test/Sema/diagnose_if.c index 38a3307d92..00bb4770f0 100644 --- a/test/Sema/diagnose_if.c +++ b/test/Sema/diagnose_if.c @@ -157,3 +157,13 @@ void runAlwaysWarnWithArg(int a) { // Bug: we would complain about `a` being undeclared if this was spelled // __diagnose_if__. void underbarName(int a) __attribute__((__diagnose_if__(a, "", "warning"))); + +// PR38095 +void constCharStar(const char *str) __attribute__((__diagnose_if__(!str[0], "empty string not allowed", "error"))); // expected-note {{from}} +void charStar(char *str) __attribute__((__diagnose_if__(!str[0], "empty string not allowed", "error"))); // expected-note {{from}} +void runConstCharStar() { + constCharStar("foo"); + charStar("bar"); + constCharStar(""); // expected-error {{empty string not allowed}} + charStar(""); // expected-error {{empty string not allowed}} +}