diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-05-21 20:36:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-05-21 20:36:58 +0000 |
commit | 3f1d6de4f742e03710d6136964af439f9cfde304 (patch) | |
tree | 7fbcb3edcc6f2d5720098ac1015c9b1a074f0a36 /clang/lib | |
parent | 47bc01786d4df534a3e8a1cc16dbf4c9606c50cc (diff) | |
download | bcm5719-llvm-3f1d6de4f742e03710d6136964af439f9cfde304.tar.gz bcm5719-llvm-3f1d6de4f742e03710d6136964af439f9cfde304.zip |
Revert r332847; it caused us to miscompile certain forms of reference initialization.
llvm-svn: 332886
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 40 |
2 files changed, 19 insertions, 33 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3efd8dc6a60..0e1fb98bf77 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10312,6 +10312,12 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result, HandleConversionToBool(Scratch.Val, Result); } +static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, + Expr::SideEffectsKind SEK) { + return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || + (SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior); +} + bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects) const { if (!getType()->isIntegralOrEnumerationType()) @@ -10319,7 +10325,7 @@ bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx, EvalResult ExprResult; if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() || - ExprResult.hasUnacceptableSideEffect(AllowSideEffects)) + hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) return false; Result = ExprResult.Val.getInt(); @@ -10333,7 +10339,7 @@ bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx, EvalResult ExprResult; if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() || - ExprResult.hasUnacceptableSideEffect(AllowSideEffects)) + hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) return false; Result = ExprResult.Val.getFloat(); @@ -10411,7 +10417,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx, bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const { EvalResult Result; return EvaluateAsRValue(Result, Ctx) && - !Result.hasUnacceptableSideEffect(SEK); + !hasUnacceptableSideEffect(Result, SEK); } APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx, diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index ae05df1be58..7b076ea3e65 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1392,40 +1392,20 @@ static QualType getNonMemoryType(CodeGenModule &CGM, QualType type) { return type; } -/// Checks if the specified initializer is equivalent to zero initialization. -static bool isZeroInitializer(ConstantEmitter &CE, const Expr *Init) { - if (auto *E = dyn_cast_or_null<CXXConstructExpr>(Init)) { - CXXConstructorDecl *CD = E->getConstructor(); - return CD->isDefaultConstructor() && CD->isTrivial(); - } - - if (auto *IL = dyn_cast_or_null<InitListExpr>(Init)) { - for (auto I : IL->inits()) - if (!isZeroInitializer(CE, I)) - return false; - if (const Expr *Filler = IL->getArrayFiller()) - return isZeroInitializer(CE, Filler); - return true; - } - - QualType InitTy = Init->getType(); - if (InitTy->isIntegralOrEnumerationType() || InitTy->isPointerType()) { - Expr::EvalResult Result; - if (Init->EvaluateAsRValue(Result, CE.CGM.getContext()) && - !Result.hasUnacceptableSideEffect(Expr::SE_NoSideEffects)) - return (Result.Val.isInt() && Result.Val.getInt().isNullValue()) || - (Result.Val.isLValue() && Result.Val.isNullPointer()); - } - - return false; -} - llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) { // Make a quick check if variable can be default NULL initialized // and avoid going through rest of code which may do, for c++11, // initialization of memory to all NULLs. - if (!D.hasLocalStorage() && isZeroInitializer(*this, D.getInit())) - return CGM.EmitNullConstant(D.getType()); + if (!D.hasLocalStorage()) { + QualType Ty = CGM.getContext().getBaseElementType(D.getType()); + if (Ty->isRecordType()) + if (const CXXConstructExpr *E = + dyn_cast_or_null<CXXConstructExpr>(D.getInit())) { + const CXXConstructorDecl *CD = E->getConstructor(); + if (CD->isTrivial() && CD->isDefaultConstructor()) + return CGM.EmitNullConstant(D.getType()); + } + } QualType destType = D.getType(); |