Diagnose binding a non-const reference to a vector element.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94963 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2010-01-31 17:18:49 +00:00
Родитель e1cd3374a8
Коммит 093802675b
6 изменённых файлов: 47 добавлений и 3 удалений

Просмотреть файл

@ -192,6 +192,9 @@ public:
return const_cast<Expr*>(this)->getBitField(); 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 /// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a /// 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 /// valid i-c-e, return false and fill in Loc (if specified) with the location

Просмотреть файл

@ -584,6 +584,8 @@ def err_reference_init_drops_quals : Error<
"qualifiers">; "qualifiers">;
def err_reference_bind_to_bitfield : Error< def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to bit-field %1">; "%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< def err_reference_var_requires_init : Error<
"declaration of reference variable %0 requires an initializer">; "declaration of reference variable %0 requires an initializer">;
def err_const_var_requires_init : Error< def err_const_var_requires_init : Error<

Просмотреть файл

@ -1977,6 +1977,25 @@ FieldDecl *Expr::getBitField() {
return 0; 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, /// isArrow - Return true if the base expression is a pointer to vector,
/// return false if the base expression is a vector. /// return false if the base expression is a vector.
bool ExtVectorElementExpr::isArrow() const { bool ExtVectorElementExpr::isArrow() const {

Просмотреть файл

@ -5968,8 +5968,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
Diag(OpLoc, diag::err_typecheck_address_of) Diag(OpLoc, diag::err_typecheck_address_of)
<< "bit-field" << op->getSourceRange(); << "bit-field" << op->getSourceRange();
return QualType(); return QualType();
} else if (isa<ExtVectorElementExpr>(op) || (isa<ArraySubscriptExpr>(op) && } else if (op->refersToVectorElement()) {
cast<ArraySubscriptExpr>(op)->getBase()->getType()->isVectorType())){
// The operand cannot be an element of a vector // The operand cannot be an element of a vector
Diag(OpLoc, diag::err_typecheck_address_of) Diag(OpLoc, diag::err_typecheck_address_of)
<< "vector element" << op->getSourceRange(); << "vector element" << op->getSourceRange();

Просмотреть файл

@ -2341,7 +2341,7 @@ static void TryReferenceInitialization(Sema &S,
if (T1Quals != T2Quals) if (T1Quals != T2Quals)
Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true); Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() && bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
Initializer->getBitField(); (Initializer->getBitField() || Initializer->refersToVectorElement());
Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary); Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
return; return;
} }
@ -3284,6 +3284,14 @@ InitializationSequence::Perform(Sema &S,
return S.ExprError(); 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. // Reference binding does not have any corresponding ASTs.
// Check exception specifications // Check exception specifications

Просмотреть файл

@ -102,3 +102,16 @@ string getInput();
void test9() { void test9() {
string &s = getInput(); // expected-error{{lvalue reference}} 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;
}