diff options
-rw-r--r-- | lib/Lex/LiteralSupport.cpp | 11 | ||||
-rw-r--r-- | test/SemaCXX/cxx2a-user-defined-literals.cpp | 27 |
2 files changed, 35 insertions, 3 deletions
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index e695b2ba37..966dafca27 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -751,7 +751,8 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){ // If we have a hex digit other than 'e' (which denotes a FP exponent) then // the code is using an incorrect base. - if (isHexDigit(*s) && *s != 'e' && *s != 'E') { + if (isHexDigit(*s) && *s != 'e' && *s != 'E' && + !isValidUDSuffix(PP.getLangOpts(), StringRef(s, ThisTokEnd - s))) { PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin), diag::err_invalid_digit) << StringRef(s, 1) << (radix == 8 ? 1 : 0); hadError = true; @@ -804,12 +805,14 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, if (!LangOpts.CPlusPlus14) return false; - // In C++1y, "s", "h", "min", "ms", "us", and "ns" are used in the library. + // In C++14, "s", "h", "min", "ms", "us", and "ns" are used in the library. // Per tweaked N3660, "il", "i", and "if" are also used in the library. + // In C++2a "d" and "y" are used in the library. return llvm::StringSwitch<bool>(Suffix) .Cases("h", "min", "s", true) .Cases("ms", "us", "ns", true) .Cases("il", "i", "if", true) + .Cases("d", "y", LangOpts.CPlusPlus2a) .Default(false); } @@ -922,7 +925,9 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { s = SkipBinaryDigits(s); if (s == ThisTokEnd) { // Done. - } else if (isHexDigit(*s)) { + } else if (isHexDigit(*s) && + !isValidUDSuffix(PP.getLangOpts(), + StringRef(s, ThisTokEnd - s))) { PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin), diag::err_invalid_digit) << StringRef(s, 1) << 2; hadError = true; diff --git a/test/SemaCXX/cxx2a-user-defined-literals.cpp b/test/SemaCXX/cxx2a-user-defined-literals.cpp new file mode 100644 index 0000000000..d730eba741 --- /dev/null +++ b/test/SemaCXX/cxx2a-user-defined-literals.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++2a %s -include %s -verify + +#ifndef INCLUDED +#define INCLUDED + +#pragma clang system_header +namespace std { + namespace chrono { + struct day{}; + struct year{}; + } + constexpr chrono::day operator"" d(unsigned long long d) noexcept; + constexpr chrono::year operator"" y(unsigned long long y) noexcept; +} + +#else + +using namespace std; +chrono::day dec_d = 5d; +chrono::day oct_d = 05d; +chrono::day bin_d = 0b011d; +// expected-error@+3{{no viable conversion from 'int' to 'chrono::day'}} +// expected-note@9{{candidate constructor (the implicit copy constructor)}} +// expected-note@9{{candidate constructor (the implicit move constructor)}} +chrono::day hex_d = 0x44d; +chrono::year y = 10y; +#endif |