diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 10 |
3 files changed, 29 insertions, 3 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 66f06e090a..b76048a2b8 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -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 { diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3b09a583cd..75be50fc0f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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(); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 5269167df2..a9adb70050 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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 |