From 7e859c0fd66b5d9e54d113974ed9bfd8098980ba Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 8 Aug 2017 22:03:54 +0000 Subject: [PATCH] Lexer: always allow imaginary constants in GNU mode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@310423 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Lex/LiteralSupport.cpp | 2 +- test/Lexer/imaginary-constants.cpp | 25 +++++++++++++++++++++++++ test/SemaCXX/constexpr-printing.cpp | 2 +- unittests/AST/DeclTest.cpp | 2 +- 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 test/Lexer/imaginary-constants.cpp diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index a598a46781..52b259edce 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -659,7 +659,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, } } // "i", "if", and "il" are user-defined suffixes in C++1y. - if (*s == 'i' && PP.getLangOpts().CPlusPlus14) + if (*s == 'i' && !PP.getLangOpts().GNUMode) break; // fall through. case 'j': diff --git a/test/Lexer/imaginary-constants.cpp b/test/Lexer/imaginary-constants.cpp new file mode 100644 index 0000000000..3a176be54a --- /dev/null +++ b/test/Lexer/imaginary-constants.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=gnu++98 -DHAVE_IMAGINARY=1 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=gnu++11 -DHAVE_IMAGINARY=1 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=gnu++14 -DHAVE_IMAGINARY=1 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -DHAVE_IMAGINARY=0 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -DHAVE_IMAGINARY=0 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -DHAVE_IMAGINARY=0 -DCXX14=1 + +// Imaginary constants are a GNU extension that became problematic when C++14 +// defined its own versions. Until then they're supported even in +// standards-compliant mode. +#if HAVE_IMAGINARY +// expected-no-diagnostics +#elif CXX14 +// expected-error@+9 {{no matching literal operator for call to 'operator""i' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template}} +// expected-error@+9 {{no matching literal operator for call to 'operator""il' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template}} +// expected-error@+9 {{invalid suffix 'ill' on integer constant}} +#else +// expected-error@+5 {{invalid suffix 'i' on integer constant}} +// expected-error@+5 {{invalid suffix 'il' on integer constant}} +// expected-error@+7 {{invalid suffix 'ill' on integer constant}} +#endif + +_Complex int val1 = 2i; +_Complex long val2 = 2il; +_Complex long long val3 = 2ill; diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp index 7f6a9c6a82..3112fdeb35 100644 --- a/test/SemaCXX/constexpr-printing.cpp +++ b/test/SemaCXX/constexpr-printing.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify -triple x86_64-linux-gnu +// RUN: %clang_cc1 %s -std=gnu++11 -fsyntax-only -verify -triple x86_64-linux-gnu struct S; constexpr int extract(const S &s); diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp index 87aeef47c6..f06f21a55d 100644 --- a/unittests/AST/DeclTest.cpp +++ b/unittests/AST/DeclTest.cpp @@ -26,7 +26,7 @@ TEST(Decl, CleansUpAPValues) { // This is a regression test for a memory leak in APValues for structs that // allocate memory. This test only fails if run under valgrind with full leak // checking enabled. - std::vector Args(1, "-std=c++11"); + std::vector Args(1, "-std=gnu++11"); Args.push_back("-fno-ms-extensions"); ASSERT_TRUE(runToolOnCodeWithArgs( Factory->create(), -- 2.40.0