Hi majnemer, mcrosier, echristo, rsmith,
In his post-review for my fix
(http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20150608/130464.html)
Richard Smith wrote:
> What about other weird kinds of lvalues, like the result of `__real` /
> `__imag`, vector indexing, and global register variables? Those have the same
> problem; CGStmt.cpp blindly calls `LValue::getAddress` without checking for
> those cases.
This patch fixes these cases:
> like the result of `__real` / `__imag`
This already works well -- no errors printed for __real (as they can be handled
just fine), a error ("invalid lvalue in asm output") is printed for __imag.
I can't create a test case that leads either to compile time fail or incorrect
code generation.
> vector indexing
Fixed
> and global register variables
Fixed
http://reviews.llvm.org/D10476
Files:
include/clang/AST/Expr.h
include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/Expr.cpp
lib/Sema/SemaStmtAsm.cpp
test/Sema/asm.c
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: test/Sema/asm.c
===================================================================
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -211,13 +211,28 @@
unsigned int field2 : 2;
unsigned int field3 : 3;
} test16_foo;
-test16_foo x;
+typedef __attribute__((vector_size(16))) int test16_bar;
+register int test16_baz asm("rbx");
+
void test16()
{
+ test16_foo a;
+ test16_bar b;
+
+ __asm__("movl $5, %0"
+ : "=rm" (a.field2)); // expected-error {{reference to a non-addressable value in asm output with a memory constraint '=rm'}}
+ __asm__("movl $5, %0"
+ :
+ : "m" (a.field3)); // expected-error {{reference to a non-addressable value in asm input with a memory constraint 'm'}}
+ __asm__("movl $5, %0"
+ : "=rm" (b[2])); // expected-error {{reference to a non-addressable value in asm output with a memory constraint '=rm'}}
+ __asm__("movl $5, %0"
+ :
+ : "m" (b[3])); // expected-error {{reference to a non-addressable value in asm input with a memory constraint 'm'}}
__asm__("movl $5, %0"
- : "=rm" (x.field2)); // expected-error {{reference to a bit-field in asm output with a memory constraint '=rm'}}
+ : "=rm" (test16_baz)); // expected-error {{reference to a non-addressable value in asm output with a memory constraint '=rm'}}
__asm__("movl $5, %0"
:
- : "m" (x.field3)); // expected-error {{reference to a bit-field in asm input with a memory constraint 'm'}}
+ : "m" (test16_baz)); // expected-error {{reference to a non-addressable value in asm input with a memory constraint 'm'}}
}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -6333,8 +6333,8 @@
"remove the cast or build with -fheinous-gnu-extensions">;
def err_invalid_asm_value_for_constraint
: Error <"value '%0' out of range for constraint '%1'">;
- def err_asm_bitfield_in_memory_constraint
- : Error <"reference to a bit-field in asm "
+ def err_asm_non_addr_value_in_memory_constraint
+ : Error <"reference to a non-addressable value in asm "
"%select{input|output}0 with a memory constraint '%1'">;
def warn_asm_label_on_auto_decl : Warning<
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -458,6 +458,10 @@
/// \brief Returns whether this expression refers to a vector element.
bool refersToVectorElement() const;
+ /// \brief Returns whether this expression refers to a global register
+ /// variable.
+ bool refersToGlobalRegisterVar() const;
+
/// \brief Returns whether this expression has a placeholder type.
bool hasPlaceholderType() const {
return getType()->isPlaceholderType();
Index: lib/Sema/SemaStmtAsm.cpp
===================================================================
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -154,12 +154,14 @@
if (CheckNakedParmReference(OutputExpr, *this))
return StmtError();
- // Bitfield can't be referenced with a pointer.
- if (Info.allowsMemory() && OutputExpr->refersToBitField())
+ // Bitfields, vector elements and global register variables can't be
+ // referenced with a pointer.
+ if (Info.allowsMemory() && (OutputExpr->refersToBitField() ||
+ OutputExpr->refersToVectorElement() ||
+ OutputExpr->refersToGlobalRegisterVar()))
return StmtError(Diag(OutputExpr->getLocStart(),
- diag::err_asm_bitfield_in_memory_constraint)
- << 1
- << Info.getConstraintStr()
+ diag::err_asm_non_addr_value_in_memory_constraint)
+ << 1 << Info.getConstraintStr()
<< OutputExpr->getSourceRange());
OutputConstraintInfos.push_back(Info);
@@ -238,12 +240,14 @@
if (CheckNakedParmReference(InputExpr, *this))
return StmtError();
- // Bitfield can't be referenced with a pointer.
- if (Info.allowsMemory() && InputExpr->refersToBitField())
+ // Bitfields, vector elements and global register variables can't be
+ // referenced with a pointer.
+ if (Info.allowsMemory() && (InputExpr->refersToBitField() ||
+ InputExpr->refersToVectorElement() ||
+ InputExpr->refersToGlobalRegisterVar()))
return StmtError(Diag(InputExpr->getLocStart(),
- diag::err_asm_bitfield_in_memory_constraint)
- << 0
- << Info.getConstraintStr()
+ diag::err_asm_non_addr_value_in_memory_constraint)
+ << 0 << Info.getConstraintStr()
<< InputExpr->getSourceRange());
// Only allow void types for memory constraints.
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -3429,6 +3429,18 @@
return false;
}
+bool Expr::refersToGlobalRegisterVar() const {
+ const Expr *E = this->IgnoreParenImpCasts();
+
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+ if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (VD->getStorageClass() == SC_Register &&
+ VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
+ 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 {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits