[cfe-commits] r154134 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/Sema/conditional-expr.c

Eli Friedman eli.friedman at gmail.com
Thu Apr 5 15:30:04 PDT 2012


Author: efriedma
Date: Thu Apr  5 17:30:04 2012
New Revision: 154134

URL: http://llvm.org/viewvc/llvm-project?rev=154134&view=rev
Log:
Properly implement the C rules for composite types for qualified pointers in conditionals.  Patch by Tim Northover.


Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/conditional-expr.c

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=154134&r1=154133&r2=154134&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Apr  5 17:30:04 2012
@@ -4568,8 +4568,28 @@
     rhptee = RHSTy->castAs<PointerType>()->getPointeeType();
   }
 
-  if (!S.Context.typesAreCompatible(lhptee.getUnqualifiedType(),
-                                    rhptee.getUnqualifiedType())) {
+  // C99 6.5.15p6: If both operands are pointers to compatible types or to
+  // differently qualified versions of compatible types, the result type is
+  // a pointer to an appropriately qualified version of the composite
+  // type.
+
+  // Only CVR-qualifiers exist in the standard, and the differently-qualified
+  // clause doesn't make sense for our extensions. E.g. address space 2 should
+  // be incompatible with address space 3: they may live on different devices or
+  // anything.
+  Qualifiers lhQual = lhptee.getQualifiers();
+  Qualifiers rhQual = rhptee.getQualifiers();
+
+  unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
+  lhQual.removeCVRQualifiers();
+  rhQual.removeCVRQualifiers();
+
+  lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual);
+  rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual);
+
+  QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee);
+
+  if (CompositeTy.isNull()) {
     S.Diag(Loc, diag::warn_typecheck_cond_incompatible_pointers)
       << LHSTy << RHSTy << LHS.get()->getSourceRange()
       << RHS.get()->getSourceRange();
@@ -4583,16 +4603,12 @@
   }
 
   // The pointer types are compatible.
-  // C99 6.5.15p6: If both operands are pointers to compatible types *or* to
-  // differently qualified versions of compatible types, the result type is
-  // a pointer to an appropriately qualified version of the *composite*
-  // type.
-  // FIXME: Need to calculate the composite type.
-  // FIXME: Need to add qualifiers
+  QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual);
+  ResultTy = S.Context.getPointerType(ResultTy);
 
-  LHS = S.ImpCastExprToType(LHS.take(), LHSTy, CK_BitCast);
-  RHS = S.ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
-  return LHSTy;
+  LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast);
+  RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast);
+  return ResultTy;
 }
 
 /// \brief Return the resulting type when the operands are both block pointers.

Modified: cfe/trunk/test/Sema/conditional-expr.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conditional-expr.c?rev=154134&r1=154133&r2=154134&view=diff
==============================================================================
--- cfe/trunk/test/Sema/conditional-expr.c (original)
+++ cfe/trunk/test/Sema/conditional-expr.c Thu Apr  5 17:30:04 2012
@@ -60,6 +60,23 @@
   test0 = test0 ? EVal : test1; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
   test0 = test0 ? test1 : EVal; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
 
+  const int *const_int;
+  int *nonconst_int;
+  *(test0 ? const_int : nonconst_int) = 42; // expected-error {{read-only variable is not assignable}}
+  *(test0 ? nonconst_int : const_int) = 42; // expected-error {{read-only variable is not assignable}}
+
+  // The composite type here should be "int (*)[12]", fine for the sizeof
+  int (*incomplete)[];
+  int (*complete)[12];
+  sizeof(*(test0 ? incomplete : complete)); // expected-warning {{expression result unused}}
+  sizeof(*(test0 ? complete : incomplete)); // expected-warning {{expression result unused}}
+
+  int __attribute__((address_space(2))) *adr2;
+  int __attribute__((address_space(3))) *adr3;
+  test0 ? adr2 : adr3; // expected-warning {{pointer type mismatch}} expected-warning {{expression result unused}}
+
+  // Make sure address-space mask ends up in the result type
+  (test0 ? (test0 ? adr2 : adr2) : nonconst_int); // expected-warning {{pointer type mismatch}} expected-warning {{expression result unused}}
 }
 
 int Postgresql() {





More information about the cfe-commits mailing list