]> granicus.if.org Git - clang/commitdiff
Fixed 22941: Integer template parameter as immediate 'I' expectes an integer constant
authorSunil Srivastava <sunil_srivastava@playstation.sony.com>
Tue, 14 Jul 2015 18:08:50 +0000 (18:08 +0000)
committerSunil Srivastava <sunil_srivastava@playstation.sony.com>
Tue, 14 Jul 2015 18:08:50 +0000 (18:08 +0000)
Basically fixed premature testing of integer constraints during template parsing
Reviewed at http://reviews.llvm.org/D10452

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242175 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaStmtAsm.cpp
test/Sema/inline-asm-validate-tmpl.cpp [new file with mode: 0644]

index d19d8819d8e234b40bd352391c20dd55dde1a633..8e3e89f1e572b99f7a1299527093ba92feee0372 100644 (file)
@@ -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/test/Sema/inline-asm-validate-tmpl.cpp b/test/Sema/inline-asm-validate-tmpl.cpp
new file mode 100644 (file)
index 0000000..cf7eac3
--- /dev/null
@@ -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); }