forked from OSchip/llvm-project
Bug fix for PR23577 (https://llvm.org/bugs/show_bug.cgi?id=23577#c0).
"1-4" specifiers are returned as numeric constants, not identifiers, and should be treated as such. Currently pragma handler incorrectly assumes that they are returned as identifiers. Patch by Andrey Bokhanko. Differential Revision: http://reviews.llvm.org/D9856 llvm-svn: 238129
This commit is contained in:
parent
654e0ca650
commit
6b080fcda5
|
@ -22,6 +22,7 @@
|
|||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/CrashRecoveryContext.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <algorithm>
|
||||
|
@ -1036,12 +1037,8 @@ struct PragmaWarningHandler : public PragmaHandler {
|
|||
|
||||
PP.Lex(Tok);
|
||||
IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
if (!II) {
|
||||
PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (II->isStr("push")) {
|
||||
if (II && II->isStr("push")) {
|
||||
// #pragma warning( push[ ,n ] )
|
||||
int Level = -1;
|
||||
PP.Lex(Tok);
|
||||
|
@ -1058,7 +1055,7 @@ struct PragmaWarningHandler : public PragmaHandler {
|
|||
}
|
||||
if (Callbacks)
|
||||
Callbacks->PragmaWarningPush(DiagLoc, Level);
|
||||
} else if (II->isStr("pop")) {
|
||||
} else if (II && II->isStr("pop")) {
|
||||
// #pragma warning( pop )
|
||||
PP.Lex(Tok);
|
||||
if (Callbacks)
|
||||
|
@ -1068,23 +1065,40 @@ struct PragmaWarningHandler : public PragmaHandler {
|
|||
// [; warning-specifier : warning-number-list...] )
|
||||
while (true) {
|
||||
II = Tok.getIdentifierInfo();
|
||||
if (!II) {
|
||||
if (!II && !Tok.is(tok::numeric_constant)) {
|
||||
PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out which warning specifier this is.
|
||||
StringRef Specifier = II->getName();
|
||||
bool SpecifierValid =
|
||||
llvm::StringSwitch<bool>(Specifier)
|
||||
.Cases("1", "2", "3", "4", true)
|
||||
.Cases("default", "disable", "error", "once", "suppress", true)
|
||||
.Default(false);
|
||||
bool SpecifierValid;
|
||||
StringRef Specifier;
|
||||
llvm::SmallString<1> SpecifierBuf;
|
||||
if (II) {
|
||||
Specifier = II->getName();
|
||||
SpecifierValid = llvm::StringSwitch<bool>(Specifier)
|
||||
.Cases("default", "disable", "error", "once",
|
||||
"suppress", true)
|
||||
.Default(false);
|
||||
// If we read a correct specifier, snatch next token (that should be
|
||||
// ":", checked later).
|
||||
if (SpecifierValid)
|
||||
PP.Lex(Tok);
|
||||
} else {
|
||||
// Token is a numeric constant. It should be either 1, 2, 3 or 4.
|
||||
uint64_t Value;
|
||||
Specifier = PP.getSpelling(Tok, SpecifierBuf);
|
||||
if (PP.parseSimpleIntegerLiteral(Tok, Value)) {
|
||||
SpecifierValid = (Value >= 1) && (Value <= 4);
|
||||
} else
|
||||
SpecifierValid = false;
|
||||
// Next token already snatched by parseSimpleIntegerLiteral.
|
||||
}
|
||||
|
||||
if (!SpecifierValid) {
|
||||
PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
|
||||
return;
|
||||
}
|
||||
PP.Lex(Tok);
|
||||
if (Tok.isNot(tok::colon)) {
|
||||
PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions
|
||||
// RUN: not %clang_cc1 %s -fms-extensions -E | FileCheck %s
|
||||
// REQUIRES: non-ps4-sdk
|
||||
|
||||
// rdar://6495941
|
||||
|
@ -7,27 +8,41 @@
|
|||
#define BAR "2"
|
||||
|
||||
#pragma comment(linker,"foo=" FOO) // expected-error {{pragma comment requires parenthesized identifier and optional string}}
|
||||
// CHECK: #pragma comment(linker,"foo=" 1)
|
||||
#pragma comment(linker," bar=" BAR)
|
||||
// CHECK: #pragma comment(linker," bar=" "2")
|
||||
|
||||
#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ )
|
||||
// CHECK: {{#pragma comment\( user, \"Compiled on \".*\" at \".*\" \)}}
|
||||
|
||||
#pragma comment(foo) // expected-error {{unknown kind of pragma comment}}
|
||||
// CHECK: #pragma comment(foo)
|
||||
#pragma comment(compiler,) // expected-error {{expected string literal in pragma comment}}
|
||||
// CHECK: #pragma comment(compiler,)
|
||||
#define foo compiler
|
||||
#pragma comment(foo) // macro expand kind.
|
||||
// CHECK: #pragma comment(compiler)
|
||||
#pragma comment(foo) x // expected-error {{pragma comment requires}}
|
||||
// CHECK: #pragma comment(compiler) x
|
||||
|
||||
#pragma comment(user, "foo\abar\nbaz\tsome thing")
|
||||
// CHECK: #pragma comment(user, "foo\abar\nbaz\tsome thing")
|
||||
|
||||
#pragma detect_mismatch("test", "1")
|
||||
// CHECK: #pragma detect_mismatch("test", "1")
|
||||
#pragma detect_mismatch() // expected-error {{expected string literal in pragma detect_mismatch}}
|
||||
// CHECK: #pragma detect_mismatch()
|
||||
#pragma detect_mismatch("test") // expected-error {{pragma detect_mismatch is malformed; it requires two comma-separated string literals}}
|
||||
// CHECK: #pragma detect_mismatch("test")
|
||||
#pragma detect_mismatch("test", 1) // expected-error {{expected string literal in pragma detect_mismatch}}
|
||||
// CHECK: #pragma detect_mismatch("test", 1)
|
||||
#pragma detect_mismatch("test", BAR)
|
||||
// CHECK: #pragma detect_mismatch("test", "2")
|
||||
|
||||
// __pragma
|
||||
|
||||
__pragma(comment(linker," bar=" BAR))
|
||||
__pragma(comment(linker," bar=" BAR))
|
||||
// CHECK: #pragma comment(linker," bar=" "2")
|
||||
|
||||
#define MACRO_WITH__PRAGMA { \
|
||||
__pragma(warning(push)); \
|
||||
|
@ -39,11 +54,16 @@ __pragma(comment(linker," bar=" BAR))
|
|||
void f()
|
||||
{
|
||||
__pragma()
|
||||
// CHECK: #pragma
|
||||
|
||||
// If we ever actually *support* __pragma(warning(disable: x)),
|
||||
// this warning should go away.
|
||||
MACRO_WITH__PRAGMA // expected-warning {{lower precedence}} \
|
||||
// expected-note 2 {{place parentheses}}
|
||||
// CHECK: #pragma warning(push)
|
||||
// CHECK: #pragma warning(disable: 10000)
|
||||
// CHECK: ; 1 + (2 > 3) ? 4 : 5;
|
||||
// CHECK: #pragma warning(pop)
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,26 +111,49 @@ void g() {}
|
|||
|
||||
// Test that we ignore pragma warning.
|
||||
#pragma warning(push)
|
||||
// CHECK: #pragma warning(push)
|
||||
#pragma warning(push, 1)
|
||||
// CHECK: #pragma warning(push, 1)
|
||||
#pragma warning(disable : 4705)
|
||||
// CHECK: #pragma warning(disable: 4705)
|
||||
#pragma warning(disable : 123 456 789 ; error : 321)
|
||||
// CHECK: #pragma warning(disable: 123 456 789)
|
||||
// CHECK: #pragma warning(error: 321)
|
||||
#pragma warning(once : 321)
|
||||
// CHECK: #pragma warning(once: 321)
|
||||
#pragma warning(suppress : 321)
|
||||
// CHECK: #pragma warning(suppress: 321)
|
||||
#pragma warning(default : 321)
|
||||
// CHECK: #pragma warning(default: 321)
|
||||
#pragma warning(pop)
|
||||
// CHECK: #pragma warning(pop)
|
||||
#pragma warning(1: 123)
|
||||
// CHECK: #pragma warning(1: 123)
|
||||
#pragma warning(2: 234 567)
|
||||
// CHECK: #pragma warning(2: 234 567)
|
||||
#pragma warning(3: 123; 4: 678)
|
||||
// CHECK: #pragma warning(3: 123)
|
||||
// CHECK: #pragma warning(4: 678)
|
||||
#pragma warning(5: 123) // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}}
|
||||
|
||||
#pragma warning(push, 0)
|
||||
// CHECK: #pragma warning(push, 0)
|
||||
// FIXME: We could probably support pushing warning level 0.
|
||||
#pragma warning(pop)
|
||||
// CHECK: #pragma warning(pop)
|
||||
|
||||
#pragma warning // expected-warning {{expected '('}}
|
||||
#pragma warning( // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}}
|
||||
#pragma warning() // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}}
|
||||
#pragma warning(push 4) // expected-warning {{expected ')'}}
|
||||
// CHECK: #pragma warning(push)
|
||||
#pragma warning(push // expected-warning {{expected ')'}}
|
||||
// CHECK: #pragma warning(push)
|
||||
#pragma warning(push, 5) // expected-warning {{requires a level between 0 and 4}}
|
||||
#pragma warning(pop, 1) // expected-warning {{expected ')'}}
|
||||
// CHECK: #pragma warning(pop)
|
||||
#pragma warning(push, 1) asdf // expected-warning {{extra tokens at end of #pragma warning directive}}
|
||||
// CHECK: #pragma warning(push, 1)
|
||||
#pragma warning(disable 4705) // expected-warning {{expected ':'}}
|
||||
#pragma warning(disable : 0) // expected-warning {{expected a warning number}}
|
||||
#pragma warning(default 321) // expected-warning {{expected ':'}}
|
||||
|
|
Loading…
Reference in New Issue