Author: tnorthover Date: Thu May 25 21:16:00 2017 New Revision: 303957 URL: http://llvm.org/viewvc/llvm-project?rev=303957&view=rev Log: Create valid LValue to represent null pointers in constant exprs
We were leaving the SubobjectDesignator in a surprising situation, where it was allegedly valid but didn't actually refer to a type. This caused a crash later on. This patch fills out the SubobjectDesignator with the pointee type (as happens in other evaluations of constant pointers) so that we don't crash later. Added: cfe/trunk/test/SemaCXX/null-cast.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=303957&r1=303956&r2=303957&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu May 25 21:16:00 2017 @@ -1230,8 +1230,7 @@ namespace { IsNullPtr = V.isNullPointer(); } - void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false, - bool IsNullPtr_ = false, uint64_t Offset_ = 0) { + void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) { #ifndef NDEBUG // We only allow a few types of invalid bases. Enforce that here. if (BInvalid) { @@ -1242,11 +1241,20 @@ namespace { #endif Base = B; - Offset = CharUnits::fromQuantity(Offset_); + Offset = CharUnits::fromQuantity(0); InvalidBase = BInvalid; CallIndex = I; Designator = SubobjectDesignator(getType(B)); - IsNullPtr = IsNullPtr_; + IsNullPtr = false; + } + + void setNull(QualType PointerTy, uint64_t TargetVal) { + Base = (Expr *)nullptr; + Offset = CharUnits::fromQuantity(TargetVal); + InvalidBase = false; + CallIndex = 0; + Designator = SubobjectDesignator(PointerTy->getPointeeType()); + IsNullPtr = true; } void setInvalid(APValue::LValueBase B, unsigned I = 0) { @@ -5494,8 +5502,8 @@ public: return true; } bool ZeroInitialization(const Expr *E) { - auto Offset = Info.Ctx.getTargetNullPointerValue(E->getType()); - Result.set((Expr*)nullptr, 0, false, true, Offset); + auto TargetVal = Info.Ctx.getTargetNullPointerValue(E->getType()); + Result.setNull(E->getType(), TargetVal); return true; } Added: cfe/trunk/test/SemaCXX/null-cast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/null-cast.cpp?rev=303957&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/null-cast.cpp (added) +++ cfe/trunk/test/SemaCXX/null-cast.cpp Thu May 25 21:16:00 2017 @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A {}; +struct B : virtual A {}; + +void foo() { + (void)static_cast<A&>(*(B *)0); // expected-warning {{binding dereferenced null pointer to reference has undefined behavior}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits