summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ExprConstant.cpp12
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp40
2 files changed, 33 insertions, 19 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 0e1fb98bf77..3efd8dc6a60 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10312,12 +10312,6 @@ 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())
@@ -10325,7 +10319,7 @@ bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx,
EvalResult ExprResult;
if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() ||
- hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
+ ExprResult.hasUnacceptableSideEffect(AllowSideEffects))
return false;
Result = ExprResult.Val.getInt();
@@ -10339,7 +10333,7 @@ bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx,
EvalResult ExprResult;
if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() ||
- hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
+ ExprResult.hasUnacceptableSideEffect(AllowSideEffects))
return false;
Result = ExprResult.Val.getFloat();
@@ -10417,7 +10411,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const {
EvalResult Result;
return EvaluateAsRValue(Result, Ctx) &&
- !hasUnacceptableSideEffect(Result, SEK);
+ !Result.hasUnacceptableSideEffect(SEK);
}
APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 7b076ea3e65..ae05df1be58 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1392,20 +1392,40 @@ 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()) {
- 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());
- }
- }
+ if (!D.hasLocalStorage() && isZeroInitializer(*this, D.getInit()))
+ return CGM.EmitNullConstant(D.getType());
QualType destType = D.getType();
OpenPOWER on IntegriCloud