зеркало из 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();
|
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;
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче