summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Bendersky <eliben@google.com>2014-06-19 18:30:15 +0000
committerEli Bendersky <eliben@google.com>2014-06-19 18:30:15 +0000
commit427d5c99b0408e4ca472b8a65d1fbd15261d7d1a (patch)
tree264d36c20c2f3a38005efbeba0deee78dc23f8ce
parent47d52751cfb3a2c0491789ccdf097879d92ad0d6 (diff)
downloadclang-427d5c99b0408e4ca472b8a65d1fbd15261d7d1a.tar.gz
clang-427d5c99b0408e4ca472b8a65d1fbd15261d7d1a.tar.bz2
clang-427d5c99b0408e4ca472b8a65d1fbd15261d7d1a.tar.xz
Fix PR20069: bad loop pragma arguments crash FE
This patch fixes a crash when handling malformed arguments to loop pragmas such as: "#pragma clang loop vectorize(()". Essentially any argument which is not an identifier or constant resulted in a crash. This patch also changes a couple of the error messages which weren't quite correct. New behavior with this patch vs old behavior: #pragma clang loop vectorize(1) OLD: error: missing keyword; expected 'enable' or 'disable' NEW: error: invalid argument; expected 'enable' or 'disable' #pragma clang loop vectorize() OLD: error: expected ')' NEW: error: missing argument to loop pragma 'vectorize' #pragma clang loop vectorize_width(bad) OLD: error: missing value; expected a positive integer value NEW: error: invalid argument; expected a positive integer value #pragma clang loop vectorize(bad) OLD: invalid keyword 'bad'; expected 'enable' or 'disable' NEW: error: invalid argument; expected 'enable' or 'disable' http://reviews.llvm.org/D4197 Patch by Mark Heffernan git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211292 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--lib/Parse/ParsePragma.cpp10
-rw-r--r--lib/Sema/SemaStmtAttr.cpp19
-rw-r--r--test/Parser/pragma-loop.cpp40
5 files changed, 44 insertions, 31 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 874e0e2049..bc097e0bf3 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -909,6 +909,8 @@ def err_omp_more_one_clause : Error<
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
"vectorize_width, interleave, interleave_count, unroll, or unroll_count">;
+def err_pragma_loop_missing_argument : Error<
+ "missing argument to loop pragma %0">;
} // end of Parse Issue category.
let CategoryName = "Modules Issue" in {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 002710e30a..b3a732e9e4 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -543,9 +543,9 @@ def err_pragma_pop_visibility_mismatch : Error<
def note_surrounding_namespace_starts_here : Note<
"surrounding namespace with visibility attribute starts here">;
def err_pragma_loop_invalid_value : Error<
- "%select{invalid|missing}0 value%select{ %1|}0; expected a positive integer value">;
+ "invalid argument; expected a positive integer value">;
def err_pragma_loop_invalid_keyword : Error<
- "%select{invalid|missing}0 keyword%select{ %1|}0; expected 'enable' or 'disable'">;
+ "invalid argument; expected 'enable' or 'disable'">;
def err_pragma_loop_compatibility : Error<
"%select{incompatible|duplicate}0 directives '%1(%2)' and '%3(%4)'">;
def err_pragma_loop_precedes_nonloop : Error<
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index c7a344f59d..2b248cc10f 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -1710,9 +1710,13 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
// FIXME: All tokens between '(' and ')' should be stored and parsed as a
// constant expression.
PP.Lex(Tok);
- Token Value;
- if (Tok.is(tok::identifier) || Tok.is(tok::numeric_constant))
- Value = Tok;
+ if (Tok.is(tok::r_paren)) {
+ // Nothing between the parentheses.
+ PP.Diag(Tok.getLocation(), diag::err_pragma_loop_missing_argument)
+ << OptionInfo;
+ return;
+ }
+ Token Value = Tok;
// Read ')'
PP.Lex(Tok);
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index c0b5ede526..44169c2fdc 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -75,18 +75,15 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave ||
Option == LoopHintAttr::Unroll) {
if (!ValueInfo) {
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
- << /*MissingKeyword=*/true << "";
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
return nullptr;
}
-
if (ValueInfo->isStr("disable"))
ValueInt = 0;
else if (ValueInfo->isStr("enable"))
ValueInt = 1;
else {
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
- << /*MissingKeyword=*/false << ValueInfo;
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
return nullptr;
}
} else if (Option == LoopHintAttr::VectorizeWidth ||
@@ -95,15 +92,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
// FIXME: We should support template parameters for the loop hint value.
// See bug report #19610.
llvm::APSInt ValueAPS;
- if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context)) {
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value)
- << /*MissingValue=*/true << "";
- return nullptr;
- }
-
- if ((ValueInt = ValueAPS.getSExtValue()) < 1) {
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value)
- << /*MissingValue=*/false << ValueInt;
+ if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context) ||
+ (ValueInt = ValueAPS.getSExtValue()) < 1) {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value);
return nullptr;
}
} else
diff --git a/test/Parser/pragma-loop.cpp b/test/Parser/pragma-loop.cpp
index 6535b62e3b..fad4feb870 100644
--- a/test/Parser/pragma-loop.cpp
+++ b/test/Parser/pragma-loop.cpp
@@ -55,6 +55,10 @@ void test(int *List, int Length) {
/* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4
/* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4
+/* expected-error {{missing argument to loop pragma 'vectorize'}} */ #pragma clang loop vectorize()
+/* expected-error {{missing argument to loop pragma 'interleave_count'}} */ #pragma clang loop interleave_count()
+/* expected-error {{missing argument to loop pragma 'unroll'}} */ #pragma clang loop unroll()
+
/* expected-error {{missing option}} */ #pragma clang loop
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
@@ -65,34 +69,46 @@ void test(int *List, int Length) {
List[i] = i;
}
-/* expected-error {{invalid value 0; expected a positive integer value}} */ #pragma clang loop vectorize_width(0)
-/* expected-error {{invalid value 0; expected a positive integer value}} */ #pragma clang loop interleave_count(0)
-/* expected-error {{invalid value 0; expected a positive integer value}} */ #pragma clang loop unroll_count(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(0)
while (i-5 < Length) {
List[i] = i;
}
-/* expected-error {{invalid value -1294967296; expected a positive integer value}} */ #pragma clang loop vectorize_width(3000000000)
-/* expected-error {{invalid value -1294967296; expected a positive integer value}} */ #pragma clang loop interleave_count(3000000000)
-/* expected-error {{invalid value -1294967296; expected a positive integer value}} */ #pragma clang loop unroll_count(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(3000000000)
while (i-6 < Length) {
List[i] = i;
}
-/* expected-error {{missing value; expected a positive integer value}} */ #pragma clang loop vectorize_width(badvalue)
-/* expected-error {{missing value; expected a positive integer value}} */ #pragma clang loop interleave_count(badvalue)
-/* expected-error {{missing value; expected a positive integer value}} */ #pragma clang loop unroll_count(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(badvalue)
while (i-6 < Length) {
List[i] = i;
}
-/* expected-error {{invalid keyword 'badidentifier'; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(badidentifier)
-/* expected-error {{invalid keyword 'badidentifier'; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(badidentifier)
-/* expected-error {{invalid keyword 'badidentifier'; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
while (i-7 < Length) {
List[i] = i;
}
+// PR20069 - Loop pragma arguments that are not identifiers or numeric
+// constants crash FE.
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(()
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(*)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(=)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(^)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(/)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(==)
+ while (i-8 < Length) {
+ List[i] = i;
+ }
+
#pragma clang loop vectorize(enable)
/* expected-error {{expected a for, while, or do-while loop to follow the '#pragma clang loop' directive}} */ int j = Length;
List[0] = List[1];