From: Sean Hunt Date: Sun, 10 Jan 2010 23:37:56 +0000 (+0000) Subject: Do not parse hexadecimal floating point literals in C++0x mode because they are X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c723404c34e9347fae473489194e8c200c4ac83;p=clang Do not parse hexadecimal floating point literals in C++0x mode because they are incompatible with user-defined literals, specifically with the following form: 0x1p+1 The preprocessing-number token extends only as far as the 'p'; the '+' is not included. Previously we could get away with this extension as p was an invalid suffix, but now with user-defined literals, 'p' might well be a valid suffix and we are forced to consider it as such. This patch also adds a warning in non-0x C++ modes telling the user that this extension is incompatible with C++0x that is enabled by default (previously and with other languages, we warn only with a compliance option such as -pedantic). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93135 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index d79091a1f6..26a80b51c8 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -84,6 +84,9 @@ def err_exponent_has_no_digits : Error<"exponent has no digits">; def ext_imaginary_constant : Extension<"imaginary constants are an extension">; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; +def ext_hexconstant_cplusplus : ExtWarn< + "hexadecimal floating constants are a C99 feature that is incompatible with " + "C++0x">; def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">; def ext_binary_literal : Extension< diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index d5a46433c3..d82f8fcf85 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -724,7 +724,8 @@ void Lexer::LexNumericConstant(Token &Result, const char *CurPtr) { return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result)); // If we have a hex FP constant, continue. - if ((C == '-' || C == '+') && (PrevCh == 'P' || PrevCh == 'p')) + if ((C == '-' || C == '+') && (PrevCh == 'P' || PrevCh == 'p') && + (!PP || !PP->getLangOptions().CPlusPlus0x)) return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result)); // Update the location of token as well as BufferPtr. diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index 9aaa82d626..5cd5497505 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -458,7 +458,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { } // A binary exponent can appear with or with a '.'. If dotted, the // binary exponent is required. - if (*s == 'p' || *s == 'P') { + if ((*s == 'p' || *s == 'P') && !PP.getLangOptions().CPlusPlus0x) { const char *Exponent = s; s++; saw_exponent = true; @@ -472,7 +472,12 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { } s = first_non_digit; - if (!PP.getLangOptions().HexFloats) + // In C++0x, we cannot support hexadecmial floating literals because + // they conflict with user-defined literals, so we warn in previous + // versions of C++ by default. + if (PP.getLangOptions().CPlusPlus) + PP.Diag(TokLoc, diag::ext_hexconstant_cplusplus); + else if (!PP.getLangOptions().HexFloats) PP.Diag(TokLoc, diag::ext_hexconstant_invalid); } else if (saw_period) { PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin), diff --git a/test/Lexer/hexfloat.cpp b/test/Lexer/hexfloat.cpp new file mode 100644 index 0000000000..5a62556ff6 --- /dev/null +++ b/test/Lexer/hexfloat.cpp @@ -0,0 +1,8 @@ +//RUN: %clang_cc1 -fsyntax-only -verify +//RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ +float f = 0x1p+1; // expected-warning {{incompatible with C++0x}} +#else +float f = 0x1p+1; // expected-warning {{invalid suffix}} +#endif