[cfe-commits] r114296 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/CodeGen/conditional-gnu-ext.c test/CodeGenCXX/gnu-conditional-scalar-ext.cpp

Fariborz Jahanian fjahanian at apple.com
Sat Sep 18 12:38:38 PDT 2010


Author: fjahanian
Date: Sat Sep 18 14:38:38 2010
New Revision: 114296

URL: http://llvm.org/viewvc/llvm-project?rev=114296&view=rev
Log:
Problem with gnu conditional extension with missing
LHS and when conditional expression is an array. Since
it will be decayed, saved expression must be saved with
decayed expression. This is necessary to preserve semantics
of this extension (and prevent an IRGen crash which expects
an array to always be decayed). I am sure there will be other
cases in c++ (aggregate conditionals for example) when saving of the 
expression must happen after some transformation on conditional
expression has happened. 
Doug, please review.  Fixes // rdar://8446940

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/CodeGen/conditional-gnu-ext.c
    cfe/trunk/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=114296&r1=114295&r2=114296&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Sep 18 14:38:38 2010
@@ -4113,9 +4113,11 @@
   QualType CheckCommaOperands( // C99 6.5.17
     Expr *lex, Expr *&rex, SourceLocation OpLoc);
   QualType CheckConditionalOperands( // C99 6.5.15
-    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
+    Expr *&cond, Expr *&lhs, Expr *&rhs, Expr *&save,
+    SourceLocation questionLoc);
   QualType CXXCheckConditionalOperands( // C++ 5.16
-    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
+    Expr *&cond, Expr *&lhs, Expr *&rhs, Expr *&save, 
+    SourceLocation questionLoc);
   QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
                                     bool *NonStandardCompositeType = 0);
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=114296&r1=114295&r2=114296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Sep 18 14:38:38 2010
@@ -4203,13 +4203,18 @@
 /// In that case, lhs = cond.
 /// C99 6.5.15
 QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
+                                        Expr *&SAVE,
                                         SourceLocation QuestionLoc) {
   // C++ is sufficiently different to merit its own checker.
   if (getLangOptions().CPlusPlus)
-    return CXXCheckConditionalOperands(Cond, LHS, RHS, QuestionLoc);
+    return CXXCheckConditionalOperands(Cond, LHS, RHS, SAVE, QuestionLoc);
 
   UsualUnaryConversions(Cond);
-  UsualUnaryConversions(LHS);
+  if (SAVE) {
+    SAVE = LHS = Cond;
+  }
+  else
+    UsualUnaryConversions(LHS);
   UsualUnaryConversions(RHS);
   QualType CondTy = Cond->getType();
   QualType LHSTy = LHS->getType();
@@ -4534,8 +4539,8 @@
     LHSExpr = SAVEExpr = CondExpr;
   }
 
-  QualType result = CheckConditionalOperands(CondExpr, LHSExpr,
-                                             RHSExpr, QuestionLoc);
+  QualType result = CheckConditionalOperands(CondExpr, LHSExpr, RHSExpr, 
+                                             SAVEExpr, QuestionLoc);
   if (result.isNull())
     return ExprError();
 

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=114296&r1=114295&r2=114296&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Sep 18 14:38:38 2010
@@ -2490,6 +2490,7 @@
 /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
 /// extension. In this case, LHS == Cond. (But they're not aliases.)
 QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
+                                           Expr *&SAVE,
                                            SourceLocation QuestionLoc) {
   // FIXME: Handle C99's complex types, vector types, block pointers and Obj-C++
   // interface pointers.
@@ -2497,6 +2498,12 @@
   // C++0x 5.16p1
   //   The first expression is contextually converted to bool.
   if (!Cond->isTypeDependent()) {
+    if (SAVE && Cond->getType()->isArrayType()) {
+      QualType CondTy = Cond->getType();
+      CondTy = Context.getArrayDecayedType(CondTy);
+      ImpCastExprToType(Cond, CondTy, CK_ArrayToPointerDecay);
+      SAVE = LHS = Cond;
+    }
     if (CheckCXXBooleanCondition(Cond))
       return QualType();
   }

Modified: cfe/trunk/test/CodeGen/conditional-gnu-ext.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/conditional-gnu-ext.c?rev=114296&r1=114295&r2=114296&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/conditional-gnu-ext.c (original)
+++ cfe/trunk/test/CodeGen/conditional-gnu-ext.c Sat Sep 18 14:38:38 2010
@@ -10,3 +10,12 @@
   return Y != 0 ? : x;
 }
 
+// rdar://8446940
+extern void abort();
+void  test1 () {
+  char x[1];
+  char *y = x ? : 0;
+
+  if (x != y)
+    abort();
+}

Modified: cfe/trunk/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp?rev=114296&r1=114295&r2=114296&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp Sat Sep 18 14:38:38 2010
@@ -9,3 +9,16 @@
     printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa);
     return 0;
 }
+
+// rdar://8446940
+namespace radar8446940 {
+extern "C" void abort();
+
+int main () {
+  char x[1];
+  char *y = x ? : 0;
+
+  if (x != y)
+    abort();
+}
+}





More information about the cfe-commits mailing list