[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