It should not be an error if an expression in inline-asm statements is not
evaluatable while parsing the template, as the failure may be due to the
presence of template paramaters, which do not have values at this stage.
This change suppresses those errors.
If the template gets used, another check is made during instantiation, and a
failure to evaluate at that time is reported as an error.
The test checks both: that the error during template parsing is not reported,
and an error detectable during instantiation is reported.
http://reviews.llvm.org/D10452
Files:
lib/Sema/SemaStmtAsm.cpp
test/Sema/inline-asm-validate-tmpl.cpp
Index: lib/Sema/SemaStmtAsm.cpp
===================================================================
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -255,17 +255,27 @@
<< InputExpr->getSourceRange());
} else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) {
llvm::APSInt Result;
- if (!InputExpr->EvaluateAsInt(Result, Context))
- return StmtError(
+ if (InputExpr->EvaluateAsInt(Result, Context)) {
+ // InputExpr is evaluatable as int. Verify that it satisfies the range
+ // constraints.
+ if (Result.slt(Info.getImmConstantMin()) ||
+ Result.sgt(Info.getImmConstantMax()))
+ return StmtError(Diag(InputExpr->getLocStart(),
+ diag::err_invalid_asm_value_for_constraint)
+ << Result.toString(10) << Info.getConstraintStr()
+ << InputExpr->getSourceRange());
+ } else {
+ // InputExpr is not evaluatable as int, but we do not consider this an
+ // error if we are parsing a template, because the reason for failure
+ // may have been the presence of template parameters in the expression.
+ // If the template is used, we will come to this point again
+ // with (getTemplateParamParent()==nullptr). That will catch the error.
+ if (getCurScope()->getTemplateParamParent() == nullptr) {
+ return StmtError(
Diag(InputExpr->getLocStart(), diag::err_asm_immediate_expected)
<< Info.getConstraintStr() << InputExpr->getSourceRange());
- if (Result.slt(Info.getImmConstantMin()) ||
- Result.sgt(Info.getImmConstantMax()))
- return StmtError(Diag(InputExpr->getLocStart(),
- diag::err_invalid_asm_value_for_constraint)
- << Result.toString(10) << Info.getConstraintStr()
- << InputExpr->getSourceRange());
-
+ }
+ }
} else {
ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
if (Result.isInvalid())
Index: test/Sema/inline-asm-validate-tmpl.cpp
===================================================================
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i686 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify %s
+
+
+// this template, when instantiated with 300, violates the range contraint
+template <int N> void test(int value)
+{
+ asm("rol %1, %0" :"=r"(value): "I"(N + 1)); // expected-error{{value '301'
out of range for constraint 'I'}}
+}
+
+int main() { test<300>(10); } // expected-note{{in instantiation of
function template specialization 'test<300>' requested here}}
+
+
+// this template is not used, but the error is detectable
+template <int N> void testb(int value)
+{
+ asm("rol %1, %0" :"=r"(value): "I"(301)); // expected-error{{value '301'
out of range for constraint 'I'}}
+}
+
+// these should compile without error
+template <int N> void testc(int value)
+{
+ asm("rol %1, %0" :"=r"(value): "I"(N + 1));
+}
+int foo() { testc<2>(10); }
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Sema/SemaStmtAsm.cpp
===================================================================
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -255,17 +255,27 @@
<< InputExpr->getSourceRange());
} else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) {
llvm::APSInt Result;
- if (!InputExpr->EvaluateAsInt(Result, Context))
- return StmtError(
+ if (InputExpr->EvaluateAsInt(Result, Context)) {
+ // InputExpr is evaluatable as int. Verify that it satisfies the range
+ // constraints.
+ if (Result.slt(Info.getImmConstantMin()) ||
+ Result.sgt(Info.getImmConstantMax()))
+ return StmtError(Diag(InputExpr->getLocStart(),
+ diag::err_invalid_asm_value_for_constraint)
+ << Result.toString(10) << Info.getConstraintStr()
+ << InputExpr->getSourceRange());
+ } else {
+ // InputExpr is not evaluatable as int, but we do not consider this an
+ // error if we are parsing a template, because the reason for failure
+ // may have been the presence of template parameters in the expression.
+ // If the template is used, we will come to this point again
+ // with (getTemplateParamParent()==nullptr). That will catch the error.
+ if (getCurScope()->getTemplateParamParent() == nullptr) {
+ return StmtError(
Diag(InputExpr->getLocStart(), diag::err_asm_immediate_expected)
<< Info.getConstraintStr() << InputExpr->getSourceRange());
- if (Result.slt(Info.getImmConstantMin()) ||
- Result.sgt(Info.getImmConstantMax()))
- return StmtError(Diag(InputExpr->getLocStart(),
- diag::err_invalid_asm_value_for_constraint)
- << Result.toString(10) << Info.getConstraintStr()
- << InputExpr->getSourceRange());
-
+ }
+ }
} else {
ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
if (Result.isInvalid())
Index: test/Sema/inline-asm-validate-tmpl.cpp
===================================================================
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i686 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify %s
+
+
+// this template, when instantiated with 300, violates the range contraint
+template <int N> void test(int value)
+{
+ asm("rol %1, %0" :"=r"(value): "I"(N + 1)); // expected-error{{value '301' out of range for constraint 'I'}}
+}
+
+int main() { test<300>(10); } // expected-note{{in instantiation of function template specialization 'test<300>' requested here}}
+
+
+// this template is not used, but the error is detectable
+template <int N> void testb(int value)
+{
+ asm("rol %1, %0" :"=r"(value): "I"(301)); // expected-error{{value '301' out of range for constraint 'I'}}
+}
+
+// these should compile without error
+template <int N> void testc(int value)
+{
+ asm("rol %1, %0" :"=r"(value): "I"(N + 1));
+}
+int foo() { testc<2>(10); }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits