[cfe-commits] r94963 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/SemaCXX/references.cpp

Anders Carlsson andersca at mac.com
Sun Jan 31 09:18:50 PST 2010


Author: andersca
Date: Sun Jan 31 11:18:49 2010
New Revision: 94963

URL: http://llvm.org/viewvc/llvm-project?rev=94963&view=rev
Log:
Diagnose binding a non-const reference to a vector element.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaCXX/references.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=94963&r1=94962&r2=94963&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sun Jan 31 11:18:49 2010
@@ -192,6 +192,9 @@
     return const_cast<Expr*>(this)->getBitField();
   }
 
+  /// \brief Returns whether this expression refers to a vector element.
+  bool refersToVectorElement() const;
+  
   /// isIntegerConstantExpr - Return true if this expression is a valid integer
   /// constant expression, and, if so, return its value in Result.  If not a
   /// valid i-c-e, return false and fill in Loc (if specified) with the location

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=94963&r1=94962&r2=94963&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Jan 31 11:18:49 2010
@@ -584,6 +584,8 @@
   "qualifiers">;
 def err_reference_bind_to_bitfield : Error<
   "%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
+def err_reference_bind_to_vector_element : Error<
+  "%select{non-const|volatile}0 reference cannot bind to vector element">;
 def err_reference_var_requires_init : Error<
   "declaration of reference variable %0 requires an initializer">;
 def err_const_var_requires_init : Error<

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

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sun Jan 31 11:18:49 2010
@@ -1977,6 +1977,25 @@
   return 0;
 }
 
+bool Expr::refersToVectorElement() const {
+  const Expr *E = this->IgnoreParens();
+  
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    if (ICE->isLvalueCast() && ICE->getCastKind() == CastExpr::CK_NoOp)
+      E = ICE->getSubExpr()->IgnoreParens();
+    else
+      break;
+  }
+  
+  if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E))
+    return ASE->getBase()->getType()->isVectorType();
+
+  if (isa<ExtVectorElementExpr>(E))
+    return true;
+
+  return false;
+}
+
 /// isArrow - Return true if the base expression is a pointer to vector,
 /// return false if the base expression is a vector.
 bool ExtVectorElementExpr::isArrow() const {

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=94963&r1=94962&r2=94963&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jan 31 11:18:49 2010
@@ -5968,8 +5968,7 @@
     Diag(OpLoc, diag::err_typecheck_address_of)
       << "bit-field" << op->getSourceRange();
         return QualType();
-  } else if (isa<ExtVectorElementExpr>(op) || (isa<ArraySubscriptExpr>(op) &&
-           cast<ArraySubscriptExpr>(op)->getBase()->getType()->isVectorType())){
+  } else if (op->refersToVectorElement()) {
     // The operand cannot be an element of a vector
     Diag(OpLoc, diag::err_typecheck_address_of)
       << "vector element" << op->getSourceRange();

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=94963&r1=94962&r2=94963&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Jan 31 11:18:49 2010
@@ -2341,7 +2341,7 @@
       if (T1Quals != T2Quals)
         Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
       bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
-           Initializer->getBitField();
+        (Initializer->getBitField() || Initializer->refersToVectorElement());
       Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
       return;
     }
@@ -3284,6 +3284,14 @@
         return S.ExprError();
       }
 
+      if (CurInitExpr->refersToVectorElement()) {
+        // Vector elements cannot bind to bit fields.
+        S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
+          << Entity.getType().isVolatileQualified()
+          << CurInitExpr->getSourceRange();
+        return S.ExprError();
+      }
+        
       // Reference binding does not have any corresponding ASTs.
 
       // Check exception specifications

Modified: cfe/trunk/test/SemaCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/references.cpp?rev=94963&r1=94962&r2=94963&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/references.cpp (original)
+++ cfe/trunk/test/SemaCXX/references.cpp Sun Jan 31 11:18:49 2010
@@ -102,3 +102,16 @@
 void test9() {
   string &s = getInput(); // expected-error{{lvalue reference}}
 }
+
+void test10() {
+  __attribute((vector_size(16))) typedef int vec4;
+  typedef __attribute__(( ext_vector_type(4) )) int ext_vec4;
+  
+  vec4 v;
+  int &a = v[0]; // expected-error{{non-const reference cannot bind to vector element}}
+  const int &b = v[0];
+  
+  ext_vec4 ev;
+  int &c = ev.x; // expected-error{{non-const reference cannot bind to vector element}}
+  const int &d = ev.x;
+}





More information about the cfe-commits mailing list