summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Lex/LiteralSupport.h6
-rw-r--r--clang/lib/Lex/LiteralSupport.cpp14
-rw-r--r--clang/test/Lexer/cxx1y_digit_separators.cpp3
3 files changed, 17 insertions, 6 deletions
diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h
index dbe9f82374d..86935d59367 100644
--- a/clang/include/clang/Lex/LiteralSupport.h
+++ b/clang/include/clang/Lex/LiteralSupport.h
@@ -108,6 +108,12 @@ private:
static bool isDigitSeparator(char C) { return C == '\''; }
+ /// \brief Determine whether the sequence of characters [Start, End) contains
+ /// any real digits (not digit separators).
+ bool containsDigits(const char *Start, const char *End) {
+ return Start != End && (Start + 1 != End || !isDigitSeparator(Start[0]));
+ }
+
enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits };
/// \brief Ensure that we don't have a digit separator here.
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index fb9d63b940b..0c0626c8a85 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -700,7 +700,7 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){
saw_exponent = true;
if (*s == '+' || *s == '-') s++; // sign
const char *first_non_digit = SkipDigits(s);
- if (first_non_digit != s) {
+ if (containsDigits(s, first_non_digit)) {
checkSeparator(TokLoc, s, CSK_BeforeDigits);
s = first_non_digit;
} else {
@@ -771,19 +771,21 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
radix = 16;
DigitsBegin = s;
s = SkipHexDigits(s);
- bool noSignificand = (s == DigitsBegin);
+ bool HasSignificandDigits = containsDigits(DigitsBegin, s);
if (s == ThisTokEnd) {
// Done.
} else if (*s == '.') {
s++;
saw_period = true;
const char *floatDigitsBegin = s;
- checkSeparator(TokLoc, s, CSK_BeforeDigits);
s = SkipHexDigits(s);
- noSignificand &= (floatDigitsBegin == s);
+ if (containsDigits(floatDigitsBegin, s))
+ HasSignificandDigits = true;
+ if (HasSignificandDigits)
+ checkSeparator(TokLoc, floatDigitsBegin, CSK_BeforeDigits);
}
- if (noSignificand) {
+ if (!HasSignificandDigits) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin),
diag::err_hexconstant_requires) << 1;
hadError = true;
@@ -799,7 +801,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
saw_exponent = true;
if (*s == '+' || *s == '-') s++; // sign
const char *first_non_digit = SkipDigits(s);
- if (first_non_digit == s) {
+ if (!containsDigits(s, first_non_digit)) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
diag::err_exponent_has_no_digits);
hadError = true;
diff --git a/clang/test/Lexer/cxx1y_digit_separators.cpp b/clang/test/Lexer/cxx1y_digit_separators.cpp
index c4c6aee963d..c076e7de057 100644
--- a/clang/test/Lexer/cxx1y_digit_separators.cpp
+++ b/clang/test/Lexer/cxx1y_digit_separators.cpp
@@ -48,6 +48,9 @@ namespace floating {
float r = 0.'0e1; // expected-error {{digit separator cannot appear at start of digit sequence}}
float s = 0.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}
float t = 0.0e'1; // expected-error {{digit separator cannot appear at start of digit sequence}}
+ float u = 0x.'p1f; // expected-error {{hexadecimal floating constants require a significand}}
+ float v = 0e'f; // expected-error {{exponent has no digits}}
+ float w = 0x0p'f; // expected-error {{exponent has no digits}}
}
#line 123'456
OpenPOWER on IntegriCloud