summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp6
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp8
-rw-r--r--clang/lib/Sema/SemaExpr.cpp26
-rw-r--r--clang/lib/Sema/SemaInit.cpp3
5 files changed, 37 insertions, 8 deletions
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 5120d4ae554..5f1eb2ce174 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2772,8 +2772,10 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T,
CmdArgs.push_back("-fno-signed-char");
}
- if (Args.hasFlag(options::OPT_fchar8__t, options::OPT_fno_char8__t, false))
- CmdArgs.push_back("-fchar8_t");
+ // The default depends on the language standard.
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_fchar8__t, options::OPT_fno_char8__t))
+ A->render(Args, CmdArgs);
if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
options::OPT_fno_short_wchar)) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 4a3195c69c3..1ea3df4303d 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2475,7 +2475,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules);
Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
- Opts.Char8 = Args.hasArg(OPT_fchar8__t);
+ Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus2a);
if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) {
Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue())
.Case("char", 1)
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index db707f46b84..b8d808f2d38 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -558,15 +558,15 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
if (LangOpts.RelaxedTemplateTemplateArgs)
Builder.defineMacro("__cpp_template_template_args", "201611L");
+ // C++20 features.
+ if (LangOpts.Char8)
+ Builder.defineMacro("__cpp_char8_t", "201811L");
+
// TS features.
if (LangOpts.ConceptsTS)
Builder.defineMacro("__cpp_experimental_concepts", "1L");
if (LangOpts.CoroutinesTS)
Builder.defineMacro("__cpp_coroutines", "201703L");
-
- // Potential future breaking changes.
- if (LangOpts.Char8)
- Builder.defineMacro("__cpp_char8_t", "201803L");
}
static void InitializePredefinedMacros(const TargetInfo &TI,
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c549514da83..980dbf9921f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1559,6 +1559,32 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
CharTy = Context.UnsignedCharTy;
}
+ // Warn on initializing an array of char from a u8 string literal; this
+ // becomes ill-formed in C++2a.
+ if (getLangOpts().CPlusPlus && !getLangOpts().CPlusPlus2a &&
+ !getLangOpts().Char8 && Kind == StringLiteral::UTF8) {
+ Diag(StringTokLocs.front(), diag::warn_cxx2a_compat_utf8_string);
+
+ // Create removals for all 'u8' prefixes in the string literal(s). This
+ // ensures C++2a compatibility (but may change the program behavior when
+ // built by non-Clang compilers for which the execution character set is
+ // not always UTF-8).
+ auto RemovalDiag = PDiag(diag::note_cxx2a_compat_utf8_string_remove_u8);
+ SourceLocation RemovalDiagLoc;
+ for (const Token &Tok : StringToks) {
+ if (Tok.getKind() == tok::utf8_string_literal) {
+ if (RemovalDiagLoc.isInvalid())
+ RemovalDiagLoc = Tok.getLocation();
+ RemovalDiag << FixItHint::CreateRemoval(CharSourceRange::getCharRange(
+ Tok.getLocation(),
+ Lexer::AdvanceToTokenCharacter(Tok.getLocation(), 2,
+ getSourceManager(), getLangOpts())));
+ }
+ }
+ Diag(RemovalDiagLoc, RemovalDiag);
+ }
+
+
QualType CharTyConst = CharTy;
// A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 438e90414d6..5249986ac03 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -8268,7 +8268,8 @@ bool InitializationSequence::Diagnose(Sema &S,
break;
case FK_UTF8StringIntoPlainChar:
S.Diag(Kind.getLocation(),
- diag::err_array_init_utf8_string_into_char);
+ diag::err_array_init_utf8_string_into_char)
+ << S.getLangOpts().CPlusPlus2a;
break;
case FK_ArrayTypeMismatch:
case FK_NonConstantArrayInit:
OpenPOWER on IntegriCloud