diff options
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 23 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/catch-undef-behavior2.cpp | 9 |
2 files changed, 17 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index f3fd60498ca..f3a5387c58d 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3023,22 +3023,15 @@ Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) { /// flow into selects in some cases. static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF) { - E = E->IgnoreParens(); - // Anything that is an integer or floating point constant is fine. - if (E->isEvaluatable(CGF.getContext())) - return true; - - // Non-volatile automatic variables too, to get "cond ? X : Y" where - // X and Y are local variables. - if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) - if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) - if (VD->hasLocalStorage() && !(CGF.getContext() - .getCanonicalType(VD->getType()) - .isVolatileQualified())) - return true; - - return false; + return E->IgnoreParens()->isEvaluatable(CGF.getContext()); + + // Even non-volatile automatic variables can't be evaluated unconditionally. + // Referencing a thread_local may cause non-trivial initialization work to + // occur. If we're inside a lambda and one of the variables is from the scope + // outside the lambda, that function may have returned already. Reading its + // locals is a bad idea. Also, these reads may introduce races there didn't + // exist in the source-level program. } diff --git a/clang/test/CodeGenCXX/catch-undef-behavior2.cpp b/clang/test/CodeGenCXX/catch-undef-behavior2.cpp new file mode 100644 index 00000000000..b8b31ca23f5 --- /dev/null +++ b/clang/test/CodeGenCXX/catch-undef-behavior2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s + +bool GetOptionalBool(bool *value); +bool GetBool(bool default_value) { + // CHECK-LABEL: @_Z7GetBoolb + // CHECK-NOT: select + bool value; + return GetOptionalBool(&value) ? value : default_value; +} |

