summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp24
-rw-r--r--clang/test/Sema/inline-asm-validate-tmpl.cpp25
2 files changed, 38 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index d19d8819d8e..8e3e89f1e57 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -254,17 +254,19 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
<< Info.getConstraintStr()
<< InputExpr->getSourceRange());
} else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) {
- llvm::APSInt Result;
- if (!InputExpr->EvaluateAsInt(Result, Context))
- 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());
+ if (!InputExpr->isValueDependent()) {
+ llvm::APSInt Result;
+ if (!InputExpr->EvaluateAsInt(Result, Context))
+ 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]);
diff --git a/clang/test/Sema/inline-asm-validate-tmpl.cpp b/clang/test/Sema/inline-asm-validate-tmpl.cpp
new file mode 100644
index 00000000000..cf7eac3d83d
--- /dev/null
+++ b/clang/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); }
OpenPOWER on IntegriCloud