зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
e1cd3374a8
Коммит
093802675b
|
@ -192,6 +192,9 @@ public:
|
|||
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
|
||||
|
|
|
@ -584,6 +584,8 @@ def err_reference_init_drops_quals : Error<
|
|||
"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<
|
||||
|
|
|
@ -1977,6 +1977,25 @@ FieldDecl *Expr::getBitField() {
|
|||
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 {
|
||||
|
|
|
@ -5968,8 +5968,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
|||
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();
|
||||
|
|
|
@ -2341,7 +2341,7 @@ static void TryReferenceInitialization(Sema &S,
|
|||
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 @@ InitializationSequence::Perform(Sema &S,
|
|||
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
|
||||
|
|
|
@ -102,3 +102,16 @@ string getInput();
|
|||
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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче