On 04/28/2010 10:16 AM, Douglas Gregor wrote:

On Apr 28, 2010, at 12:34 AM, Sean Hunt wrote:

The attached patch makes the following obtuse testcase succeed:

volatile int i;

const int&  i = i++;

Thanks for reviewing,

The patch is empty (?)

        - Doug

Oops. Here's a proper version.

Sean
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index fb65862..becd751 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -4212,7 +4212,7 @@ public:
   /// type checking unary operators (subroutines of ActOnUnaryOp).
   /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
   QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
-                                          bool isInc);
+                                          bool isInc, bool isPrefix);
   QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
   QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
   QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc, bool isReal);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index bdd1cfb..b667f3b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5854,7 +5854,7 @@ QualType Sema::CheckCommaOperands(Expr *LHS, Expr *&RHS, SourceLocation Loc) {
 /// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
 /// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
 QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
-                                              bool isInc) {
+                                              bool isInc, bool isPrefix) {
   if (Op->isTypeDependent())
     return Context.DependentTy;
 
@@ -5917,7 +5917,11 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
   // Now make sure the operand is a modifiable lvalue.
   if (CheckForModifiableLvalue(Op, OpLoc, *this))
     return QualType();
-  return ResType;
+  // In C++, a prefix increment is the same type as the operand. Otherwise
+  // (in C or with postfix), the increment is the unqualified type of the
+  // operand.
+  return isPrefix && getLangOptions().CPlusPlus
+    ? ResType : ResType.getUnqualifiedType();
 }
 
 /// getPrimaryDecl - Helper function for CheckAddressOfOperand().
@@ -6457,7 +6461,9 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
   case UnaryOperator::PostDec:
     resultType = CheckIncrementDecrementOperand(Input, OpLoc,
                                                 Opc == UnaryOperator::PreInc ||
-                                                Opc == UnaryOperator::PostInc);
+                                                Opc == UnaryOperator::PostInc,
+                                                Opc == UnaryOperator::PreInc ||
+                                                Opc == UnaryOperator::PreDec);
     break;
   case UnaryOperator::AddrOf:
     resultType = CheckAddressOfOperand(Input, OpLoc);
diff --git a/test/SemaCXX/inc-decrement-qualifiers.cpp b/test/SemaCXX/inc-decrement-qualifiers.cpp
new file mode 100644
index 0000000..ba837a9
--- /dev/null
+++ b/test/SemaCXX/inc-decrement-qualifiers.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+volatile int i;
+
+const int &inc = i++;
+const int &dec = i--;
+
+const int &incfail = ++i; // expected-error {{drops qualifiers}}
+const int &decfail = --i; // expected-error {{drops qualifiers}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to