[cfe-commits] r60954 - in /cfe/trunk: docs/InternalsManual.html lib/AST/Expr.cpp test/Sema/i-c-e.c

Chris Lattner sabre at nondot.org
Fri Dec 12 10:00:51 PST 2008


Author: lattner
Date: Fri Dec 12 12:00:51 2008
New Revision: 60954

URL: http://llvm.org/viewvc/llvm-project?rev=60954&view=rev
Log:
Implement the final (hopefully) wrinkle to i-c-e + builtin_constant_p 
processing: it allows arbitrary foldable constants as the operand of ?: when
builtin_constant_p is the condition.

Modified:
    cfe/trunk/docs/InternalsManual.html
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/test/Sema/i-c-e.c

Modified: cfe/trunk/docs/InternalsManual.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.html?rev=60954&r1=60953&r2=60954&view=diff

==============================================================================
--- cfe/trunk/docs/InternalsManual.html (original)
+++ cfe/trunk/docs/InternalsManual.html Fri Dec 12 12:00:51 2008
@@ -1155,7 +1155,8 @@
     constant expression) if the operand is any evaluatable constant.  As a
     special case, if <tt>__builtin_constant_p</tt> is the (potentially
     parenthesized) condition of a conditional operator expression ("?:"), only
-    the true side of the conditional operator is considered.</li>
+    the true side of the conditional operator is considered, and it is evaluated
+    with full constant folding.</li>
 <li><b><tt>__builtin_choose_expr</tt></b>: The condition is required to be an
     integer constant expression, but we accept any constant as an "extension of
     an extension".  This only evaluates one operand depending on which way the

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=60954&r1=60953&r2=60954&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Dec 12 12:00:51 2008
@@ -1028,14 +1028,18 @@
     
     // If the condition (ignoring parens) is a __builtin_constant_p call, 
     // then only the true side is actually considered in an integer constant
-    // expression.  This is an important GNU extension.
-    //
-    // FIXME: ?: with a conditional expr should arguably be an i-c-e if the true
-    // side can be folded in any way to a constant.  See GCC PR38377 for
-    // discussion.
+    // expression, and it is fully evaluated.  This is an important GNU
+    // extension.  See GCC PR38377 for discussion.
     if (const CallExpr *CallCE = dyn_cast<CallExpr>(Cond->IgnoreParenCasts()))
-      if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p)
-        FalseExp = 0;
+      if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p) {
+        EvalResult EVResult;
+        if (!Evaluate(EVResult, Ctx) || EVResult.HasSideEffects)
+          return false;
+        assert(EVResult.Val.isInt() && "FP conditional expr not expected");
+        Result = EVResult.Val.getInt();
+        if (Loc) *Loc = EVResult.DiagLoc;
+        return true;
+      }
     
     // Evaluate the false one first, discard the result.
     if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))

Modified: cfe/trunk/test/Sema/i-c-e.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/i-c-e.c?rev=60954&r1=60953&r2=60954&view=diff

==============================================================================
--- cfe/trunk/test/Sema/i-c-e.c (original)
+++ cfe/trunk/test/Sema/i-c-e.c Fri Dec 12 12:00:51 2008
@@ -7,6 +7,19 @@
 char w[__builtin_constant_p(expr) ? expr : 1];
 
 
+// __builtin_constant_p as the condition of ?: allows arbitrary foldable
+// constants to be transmogrified into i-c-e's.
+char b[__builtin_constant_p((int)(1.0+2.0)) ? (int)(1.0+2.0) : -1];
+
+struct c {
+  int a : (  // expected-error {{expression is not an integer constant expression}}
+           __builtin_constant_p((int)(1.0+2.0)) ? (int)(1.0+
+     expr  // expected-note {{subexpression not valid in an integer constant expression}}
+           ) : -1);
+};
+
+
+
 
 void test1(int n, int* p) { *(n ? p : (void *)(7-7)) = 1; }
 void test2(int n, int* p) { *(n ? p : (void *)0) = 1; }





More information about the cfe-commits mailing list