Tyker updated this revision to Diff 199830.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62009/new/

https://reviews.llvm.org/D62009

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/builtin-is-constant-evaluated.cpp

Index: clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
===================================================================
--- clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
+++ clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
@@ -119,3 +119,11 @@
 };
 TestConditionalExplicit e = 42;
 #endif
+
+constexpr int i = (long long)__builtin_is_constant_evaluated() * (1ll << 33);
+// expected-warning@-1 {{implicit conversion}}
+
+void f() {
+  if constexpr ((long long)__builtin_is_constant_evaluated() * (1ll << 33))
+                 ;// expected-error@-1 {{cannot be narrowed to type 'bool'}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -5408,6 +5408,7 @@
   if (checkPlaceholderForOverload(S, From))
     return ExprError();
 
+  From->setIsConstantContext();
   // C++1z [expr.const]p3:
   //  A converted constant expression of type T is an expression,
   //  implicitly converted to type T, where the converted
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11100,6 +11100,10 @@
       return;
   }
 
+  Init->setIsConstantContext(
+      VDecl->isConstexpr() ||
+      (VDecl->getType().isConstQualified() && !Init->isValueDependent()));
+
   // dllimport cannot be used on variable definitions.
   if (VDecl->hasAttr<DLLImportAttr>() && !VDecl->isStaticDataMember()) {
     Diag(VDecl->getLocation(), diag::err_attribute_dllimport_data_definition);
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -11439,7 +11439,7 @@
 bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
                             bool InConstantContext) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
-  Info.InConstantContext = InConstantContext;
+  Info.InConstantContext = InConstantContext || IsConstantContext();
   return ::EvaluateAsRValue(this, Result, Ctx, Info);
 }
 
@@ -11453,12 +11453,14 @@
 bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
                          SideEffectsKind AllowSideEffects) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+  Info.InConstantContext = IsConstantContext();
   return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
 }
 
 bool Expr::EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
                                 SideEffectsKind AllowSideEffects) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+  Info.InConstantContext = IsConstantContext();
   return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info);
 }
 
@@ -11478,7 +11480,7 @@
 
 bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
-
+  Info.InConstantContext = IsConstantContext();
   LValue LV;
   if (!EvaluateLValue(this, LV, Info) || Result.HasSideEffects ||
       !CheckLValueConstantExpression(Info, getExprLoc(),
@@ -11588,6 +11590,7 @@
   EvalResult EVResult;
   if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
     EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
+    Info.InConstantContext = IsConstantContext();
     (void)::EvaluateAsRValue(Info, this, EVResult.Val);
   }
 }
@@ -12115,6 +12118,7 @@
   SmallVector<PartialDiagnosticAt, 8> Diags;
   Status.Diag = &Diags;
   EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+  Info.InConstantContext = IsConstantContext();
 
   APValue Scratch;
   bool IsConstExpr = ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch);
Index: clang/include/clang/AST/Stmt.h
===================================================================
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -318,8 +318,9 @@
     unsigned ValueDependent : 1;
     unsigned InstantiationDependent : 1;
     unsigned ContainsUnexpandedParameterPack : 1;
+    unsigned IsConstantContext : 1;
   };
-  enum { NumExprBits = NumStmtBits + 9 };
+  enum { NumExprBits = NumStmtBits + 10 };
 
   class PredefinedExprBitfields {
     friend class ASTStmtReader;
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -223,6 +223,18 @@
     ExprBits.ContainsUnexpandedParameterPack = PP;
   }
 
+  /// Wether this expression and all its subexpression should be evaluated in
+  /// constant context.
+  bool IsConstantContext() const {
+    return ExprBits.IsConstantContext;
+  }
+
+  /// Set the bits that indicate this expression and all its subexpression
+  /// should be evaluated in constant context.
+  void setIsConstantContext(bool IsConstantContext = true) {
+    ExprBits.IsConstantContext = IsConstantContext;
+  }
+
   /// getExprLoc - Return the preferred location for the arrow when diagnosing
   /// a problem with a generic expression.
   SourceLocation getExprLoc() const LLVM_READONLY;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to