Add -std=c++20 flag, replace C++2a with C++20 throughout the Clang

user interface and documentation, and update __cplusplus for C++20.

WG21 considers the C++20 standard to be finished (even though it still
has some more steps to pass through in the ISO process).

The old flag names are accepted for compatibility, as usual, and we
still have lots of references to C++2a in comments and identifiers;
those can be cleaned up separately.
This commit is contained in:
Richard Smith 2020-02-18 16:13:23 -08:00
parent 7a4ddfb774
commit 24ad121582
34 changed files with 312 additions and 292 deletions

View File

@ -122,7 +122,7 @@ of ``cxx_rvalue_references``.
``__has_cpp_attribute`` ``__has_cpp_attribute``
----------------------- -----------------------
This function-like macro is available in C++2a by default, and is provided as an This function-like macro is available in C++20 by default, and is provided as an
extension in earlier language standards. It takes a single argument that is the extension in earlier language standards. It takes a single argument that is the
name of a double-square-bracket-style attribute. The argument can either be a name of a double-square-bracket-style attribute. The argument can either be a
single identifier or a scoped identifier. If the attribute is supported, a single identifier or a scoped identifier. If the attribute is supported, a

View File

@ -13,7 +13,7 @@ def note_expr_divide_by_zero : Note<"division by zero">;
def note_constexpr_invalid_cast : Note< def note_constexpr_invalid_cast : Note<
"%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of" "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of"
" a reinterpret_cast|cast from %1}0 is not allowed in a constant expression" " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression"
"%select{| in C++ standards before C++2a||}0">; "%select{| in C++ standards before C++20||}0">;
def note_constexpr_invalid_downcast : Note< def note_constexpr_invalid_downcast : Note<
"cannot cast object of dynamic type %0 to type %1">; "cannot cast object of dynamic type %0 to type %1">;
def note_constexpr_overflow : Note< def note_constexpr_overflow : Note<
@ -33,7 +33,7 @@ def note_constexpr_no_return : Note<
"control reached end of constexpr function">; "control reached end of constexpr function">;
def note_constexpr_virtual_call : Note< def note_constexpr_virtual_call : Note<
"cannot evaluate call to virtual function in a constant expression " "cannot evaluate call to virtual function in a constant expression "
"in C++ standards before C++2a">; "in C++ standards before C++20">;
def note_constexpr_pure_virtual_call : Note< def note_constexpr_pure_virtual_call : Note<
"pure virtual function %q0 called">; "pure virtual function %q0 called">;
def note_constexpr_polymorphic_unknown_dynamic_type : Note< def note_constexpr_polymorphic_unknown_dynamic_type : Note<
@ -105,7 +105,7 @@ def note_constexpr_var_init_non_constant : Note<
"initializer of %0 is not a constant expression">; "initializer of %0 is not a constant expression">;
def note_constexpr_typeid_polymorphic : Note< def note_constexpr_typeid_polymorphic : Note<
"typeid applied to expression of polymorphic type %0 is " "typeid applied to expression of polymorphic type %0 is "
"not allowed in a constant expression in C++ standards before C++2a">; "not allowed in a constant expression in C++ standards before C++20">;
def note_constexpr_void_comparison : Note< def note_constexpr_void_comparison : Note<
"comparison between unequal pointers to void has unspecified result">; "comparison between unequal pointers to void has unspecified result">;
def note_constexpr_temporary_here : Note<"temporary created here">; def note_constexpr_temporary_here : Note<"temporary created here">;

View File

@ -120,7 +120,7 @@ def err_enum_template : Error<"enumeration cannot be a template">;
def warn_cxx20_compat_consteval : Warning< def warn_cxx20_compat_consteval : Warning<
"'consteval' specifier is incompatible with C++ standards before C++20">, "'consteval' specifier is incompatible with C++ standards before C++20">,
InGroup<CXX2aCompat>, DefaultIgnore; InGroup<CXX20Compat>, DefaultIgnore;
} }

View File

@ -106,7 +106,7 @@ def err_fe_invalid_wchar_type
def err_fe_invalid_exception_model def err_fe_invalid_exception_model
: Error<"invalid exception model '%0' for target '%1'">; : Error<"invalid exception model '%0' for target '%1'">;
def warn_fe_concepts_ts_flag : Warning< def warn_fe_concepts_ts_flag : Warning<
"-fconcepts-ts is deprecated - use '-std=c++2a' for Concepts support">, "-fconcepts-ts is deprecated - use '-std=c++20' for Concepts support">,
InGroup<Deprecated>; InGroup<Deprecated>;
def warn_fe_serialized_diag_merge_failure : Warning< def warn_fe_serialized_diag_merge_failure : Warning<
@ -175,9 +175,9 @@ def note_incompatible_analyzer_plugin_api : Note<
def err_module_build_requires_fmodules : Error< def err_module_build_requires_fmodules : Error<
"module compilation requires '-fmodules'">; "module compilation requires '-fmodules'">;
def err_module_interface_requires_cpp_modules : Error< def err_module_interface_requires_cpp_modules : Error<
"module interface compilation requires '-std=c++2a' or '-fmodules-ts'">; "module interface compilation requires '-std=c++20' or '-fmodules-ts'">;
def err_header_module_requires_modules : Error< def err_header_module_requires_modules : Error<
"header module compilation requires '-fmodules', '-std=c++2a', or " "header module compilation requires '-fmodules', '-std=c++20', or "
"'-fmodules-ts'">; "'-fmodules-ts'">;
def warn_module_config_mismatch : Warning< def warn_module_config_mismatch : Warning<
"module file %0 cannot be loaded due to a configuration mismatch with the current " "module file %0 cannot be loaded due to a configuration mismatch with the current "

View File

@ -187,10 +187,10 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedWritableStr]>, DeprecatedWritableStr]>,
DiagCategory<"Deprecations">; DiagCategory<"Deprecations">;
def CXX2aDesignator : DiagGroup<"c++2a-designator">; def CXX20Designator : DiagGroup<"c++20-designator">;
// Allow -Wno-c99-designator to be used to turn off all warnings on valid C99 // Allow -Wno-c99-designator to be used to turn off all warnings on valid C99
// designators (including the warning controlled by -Wc++2a-designator). // designators (including the warning controlled by -Wc++20-designator).
def C99Designator : DiagGroup<"c99-designator", [CXX2aDesignator]>; def C99Designator : DiagGroup<"c99-designator", [CXX20Designator]>;
def GNUDesignator : DiagGroup<"gnu-designator">; def GNUDesignator : DiagGroup<"gnu-designator">;
def DtorName : DiagGroup<"dtor-name">; def DtorName : DiagGroup<"dtor-name">;
@ -247,9 +247,9 @@ def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">; def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">;
def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic", def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
[CXXPre17Compat]>; [CXXPre17Compat]>;
def CXXPre2aCompat : DiagGroup<"c++98-c++11-c++14-c++17-compat">; def CXXPre20Compat : DiagGroup<"c++98-c++11-c++14-c++17-compat">;
def CXXPre2aCompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic", def CXXPre20CompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic",
[CXXPre2aCompat]>; [CXXPre20Compat]>;
def CXX98CompatBindToTemporaryCopy : def CXX98CompatBindToTemporaryCopy :
DiagGroup<"c++98-compat-bind-to-temporary-copy">; DiagGroup<"c++98-compat-bind-to-temporary-copy">;
@ -263,7 +263,7 @@ def CXX98Compat : DiagGroup<"c++98-compat",
CXX98CompatUnnamedTypeTemplateArgs, CXX98CompatUnnamedTypeTemplateArgs,
CXXPre14Compat, CXXPre14Compat,
CXXPre17Compat, CXXPre17Compat,
CXXPre2aCompat]>; CXXPre20Compat]>;
// Warnings for C++11 features which are Extensions in C++98 mode. // Warnings for C++11 features which are Extensions in C++98 mode.
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
[CXX98Compat, [CXX98Compat,
@ -271,7 +271,7 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
CXX98CompatExtraSemi, CXX98CompatExtraSemi,
CXXPre14CompatPedantic, CXXPre14CompatPedantic,
CXXPre17CompatPedantic, CXXPre17CompatPedantic,
CXXPre2aCompatPedantic]>; CXXPre20CompatPedantic]>;
def CXX11Narrowing : DiagGroup<"c++11-narrowing">; def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
@ -297,33 +297,35 @@ def CXX11Compat : DiagGroup<"c++11-compat",
CXX11CompatDeprecatedWritableStr, CXX11CompatDeprecatedWritableStr,
CXXPre14Compat, CXXPre14Compat,
CXXPre17Compat, CXXPre17Compat,
CXXPre2aCompat]>; CXXPre20Compat]>;
def : DiagGroup<"c++0x-compat", [CXX11Compat]>; def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic", def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
[CXX11Compat, [CXX11Compat,
CXXPre14CompatPedantic, CXXPre14CompatPedantic,
CXXPre17CompatPedantic, CXXPre17CompatPedantic,
CXXPre2aCompatPedantic]>; CXXPre20CompatPedantic]>;
def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat, def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat,
CXXPre2aCompat]>; CXXPre20Compat]>;
def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic", def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
[CXX14Compat, [CXX14Compat,
CXXPre17CompatPedantic, CXXPre17CompatPedantic,
CXXPre2aCompatPedantic]>; CXXPre20CompatPedantic]>;
def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister, def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister,
DeprecatedIncrementBool, DeprecatedIncrementBool,
CXX17CompatMangling, CXX17CompatMangling,
CXXPre2aCompat]>; CXXPre20Compat]>;
def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic", def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic",
[CXX17Compat, [CXX17Compat,
CXXPre2aCompatPedantic]>; CXXPre20CompatPedantic]>;
def : DiagGroup<"c++1z-compat", [CXX17Compat]>; def : DiagGroup<"c++1z-compat", [CXX17Compat]>;
def CXX2aCompat : DiagGroup<"c++2a-compat">; def CXX20Compat : DiagGroup<"c++20-compat">;
def CXX2aCompatPedantic : DiagGroup<"c++2a-compat-pedantic", def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic",
[CXX2aCompat]>; [CXX20Compat]>;
def : DiagGroup<"c++2a-compat", [CXX20Compat]>;
def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>;
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">; def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
@ -959,13 +961,14 @@ def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>;
// earlier C++ versions. // earlier C++ versions.
def CXX17 : DiagGroup<"c++17-extensions">; def CXX17 : DiagGroup<"c++17-extensions">;
// A warning group for warnings about using C++2a features as extensions in // A warning group for warnings about using C++20 features as extensions in
// earlier C++ versions. // earlier C++ versions.
def CXX2a : DiagGroup<"c++2a-extensions", [CXX2aDesignator]>; def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator]>;
def : DiagGroup<"c++0x-extensions", [CXX11]>; def : DiagGroup<"c++0x-extensions", [CXX11]>;
def : DiagGroup<"c++1y-extensions", [CXX14]>; def : DiagGroup<"c++1y-extensions", [CXX14]>;
def : DiagGroup<"c++1z-extensions", [CXX17]>; def : DiagGroup<"c++1z-extensions", [CXX17]>;
def : DiagGroup<"c++2a-extensions", [CXX20]>;
def DelegatingCtorCycles : def DelegatingCtorCycles :
DiagGroup<"delegating-ctor-cycles">; DiagGroup<"delegating-ctor-cycles">;

View File

@ -31,12 +31,12 @@ def warn_cxx98_compat_less_colon_colon : Warning<
InGroup<CXX98Compat>, DefaultIgnore; InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx17_compat_spaceship : Warning< def warn_cxx17_compat_spaceship : Warning<
"'<=>' operator is incompatible with C++ standards before C++2a">, "'<=>' operator is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def warn_cxx2a_compat_spaceship : Warning< def warn_cxx2a_compat_spaceship : Warning<
"'<=>' is a single token in C++2a; " "'<=>' is a single token in C++20; "
"add a space to avoid a change in behavior">, "add a space to avoid a change in behavior">,
InGroup<CXX2aCompat>; InGroup<CXX20Compat>;
// Trigraphs. // Trigraphs.
def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>; def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
@ -78,8 +78,8 @@ def ext_token_used : Extension<"extension used">,
def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">, def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
InGroup<CXX11Compat>, DefaultIgnore; InGroup<CXX11Compat>, DefaultIgnore;
def warn_cxx2a_keyword : Warning<"'%0' is a keyword in C++2a">, def warn_cxx2a_keyword : Warning<"'%0' is a keyword in C++20">,
InGroup<CXX2aCompat>, DefaultIgnore; InGroup<CXX20Compat>, DefaultIgnore;
def ext_unterminated_char_or_string : ExtWarn< def ext_unterminated_char_or_string : ExtWarn<
"missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>; "missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;

View File

@ -241,10 +241,10 @@ def warn_cxx14_compat_nested_namespace_definition : Warning<
"nested namespace definition is incompatible with C++ standards before C++17">, "nested namespace definition is incompatible with C++ standards before C++17">,
InGroup<CXXPre17Compat>, DefaultIgnore; InGroup<CXXPre17Compat>, DefaultIgnore;
def ext_inline_nested_namespace_definition : ExtWarn< def ext_inline_nested_namespace_definition : ExtWarn<
"inline nested namespace definition is a C++2a extension">, InGroup<CXX2a>; "inline nested namespace definition is a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_inline_nested_namespace_definition : Warning< def warn_cxx17_compat_inline_nested_namespace_definition : Warning<
"inline nested namespace definition is incompatible with C++ standards before" "inline nested namespace definition is incompatible with C++ standards before"
" C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; " C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_inline_nested_namespace_definition : Error< def err_inline_nested_namespace_definition : Error<
"nested namespace definition cannot be 'inline'">; "nested namespace definition cannot be 'inline'">;
def err_expected_semi_after_attribute_list : Error< def err_expected_semi_after_attribute_list : Error<
@ -589,11 +589,11 @@ def warn_cxx14_compat_init_statement : Warning<
"%select{if|switch}0 initialization statements are incompatible with " "%select{if|switch}0 initialization statements are incompatible with "
"C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>; "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
def ext_for_range_init_stmt : ExtWarn< def ext_for_range_init_stmt : ExtWarn<
"range-based for loop initialization statements are a C++2a extension">, "range-based for loop initialization statements are a C++20 extension">,
InGroup<CXX2a>; InGroup<CXX20>;
def warn_cxx17_compat_for_range_init_stmt : Warning< def warn_cxx17_compat_for_range_init_stmt : Warning<
"range-based for loop initialization statements are incompatible with " "range-based for loop initialization statements are incompatible with "
"C++ standards before C++2a">, DefaultIgnore, InGroup<CXXPre2aCompat>; "C++ standards before C++20">, DefaultIgnore, InGroup<CXXPre20Compat>;
def warn_empty_init_statement : Warning< def warn_empty_init_statement : Warning<
"empty initialization statement of '%select{if|switch|range-based for}0' " "empty initialization statement of '%select{if|switch|range-based for}0' "
"has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore; "has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
@ -681,13 +681,13 @@ def err_ms_property_initializer : Error<
"property declaration cannot have an in-class initializer">; "property declaration cannot have an in-class initializer">;
def warn_cxx2a_compat_explicit_bool : Warning< def warn_cxx2a_compat_explicit_bool : Warning<
"this expression will be parsed as explicit(bool) in C++2a">, "this expression will be parsed as explicit(bool) in C++20">,
InGroup<CXX2aCompat>, DefaultIgnore; InGroup<CXX20Compat>, DefaultIgnore;
def warn_cxx17_compat_explicit_bool : Warning< def warn_cxx17_compat_explicit_bool : Warning<
"explicit(bool) is incompatible with C++ standards before C++2a">, "explicit(bool) is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++2a extension">, def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++20 extension">,
InGroup<CXX2a>; InGroup<CXX20>;
/// C++ Templates /// C++ Templates
def err_expected_template : Error<"expected template">; def err_expected_template : Error<"expected template">;
@ -844,11 +844,11 @@ def warn_cxx98_compat_nonstatic_member_init : Warning<
"in-class initialization of non-static data members is incompatible with C++98">, "in-class initialization of non-static data members is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore; InGroup<CXX98Compat>, DefaultIgnore;
def ext_bitfield_member_init: ExtWarn< def ext_bitfield_member_init: ExtWarn<
"default member initializer for bit-field is a C++2a extension">, "default member initializer for bit-field is a C++20 extension">,
InGroup<CXX2a>; InGroup<CXX20>;
def warn_cxx17_compat_bitfield_member_init: Warning< def warn_cxx17_compat_bitfield_member_init: Warning<
"default member initializer for bit-field is incompatible with " "default member initializer for bit-field is incompatible with "
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_incomplete_array_member_init: Error< def err_incomplete_array_member_init: Error<
"array bound cannot be deduced from an in-class initializer">; "array bound cannot be deduced from an in-class initializer">;
@ -944,13 +944,13 @@ def warn_cxx14_compat_constexpr_on_lambda : Warning<
def ext_constexpr_on_lambda_cxx17 : ExtWarn< def ext_constexpr_on_lambda_cxx17 : ExtWarn<
"'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>; "'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>;
// C++2a template lambdas // C++20 template lambdas
def ext_lambda_template_parameter_list: ExtWarn< def ext_lambda_template_parameter_list: ExtWarn<
"explicit template parameter list for lambdas is a C++2a extension">, "explicit template parameter list for lambdas is a C++20 extension">,
InGroup<CXX2a>; InGroup<CXX20>;
def warn_cxx17_compat_lambda_template_parameter_list: Warning< def warn_cxx17_compat_lambda_template_parameter_list: Warning<
"explicit template parameter list for lambdas is incompatible with " "explicit template parameter list for lambdas is incompatible with "
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_lambda_template_parameter_list_empty : Error< def err_lambda_template_parameter_list_empty : Error<
"lambda template parameter list cannot be empty">; "lambda template parameter list cannot be empty">;
@ -1409,7 +1409,7 @@ let CategoryName = "Concepts Issue" in {
def err_concept_definition_not_identifier : Error< def err_concept_definition_not_identifier : Error<
"name defined in concept definition must be an identifier">; "name defined in concept definition must be an identifier">;
def ext_concept_legacy_bool_keyword : ExtWarn< def ext_concept_legacy_bool_keyword : ExtWarn<
"ISO C++2a does not permit the 'bool' keyword after 'concept'">, "ISO C++20 does not permit the 'bool' keyword after 'concept'">,
InGroup<DiagGroup<"concepts-ts-compat">>; InGroup<DiagGroup<"concepts-ts-compat">>;
def err_placeholder_expected_auto_or_decltype_auto : Error< def err_placeholder_expected_auto_or_decltype_auto : Error<
"expected 'auto' or 'decltype(auto)' after concept name">; "expected 'auto' or 'decltype(auto)' after concept name">;

View File

@ -193,10 +193,10 @@ def ext_flexible_array_init : Extension<
// C++20 designated initializers // C++20 designated initializers
def ext_cxx_designated_init : Extension< def ext_cxx_designated_init : Extension<
"designated initializers are a C++20 extension">, InGroup<CXX2aDesignator>; "designated initializers are a C++20 extension">, InGroup<CXX20Designator>;
def warn_cxx17_compat_designated_init : Warning< def warn_cxx17_compat_designated_init : Warning<
"designated initializers are incompatible with C++ standards before C++20">, "designated initializers are incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompatPedantic>, DefaultIgnore; InGroup<CXXPre20CompatPedantic>, DefaultIgnore;
def ext_designated_init_mixed : ExtWarn< def ext_designated_init_mixed : ExtWarn<
"mixture of designated and non-designated initializers in the same " "mixture of designated and non-designated initializers in the same "
"initializer list is a C99 extension">, InGroup<C99Designator>; "initializer list is a C99 extension">, InGroup<C99Designator>;
@ -444,13 +444,13 @@ def err_decomp_decl_spec : Error<
"%plural{1:'%1'|:with '%1' specifiers}0">; "%plural{1:'%1'|:with '%1' specifiers}0">;
def ext_decomp_decl_spec : ExtWarn< def ext_decomp_decl_spec : ExtWarn<
"decomposition declaration declared " "decomposition declaration declared "
"%plural{1:'%1'|:with '%1' specifiers}0 is a C++2a extension">, "%plural{1:'%1'|:with '%1' specifiers}0 is a C++20 extension">,
InGroup<CXX2a>; InGroup<CXX20>;
def warn_cxx17_compat_decomp_decl_spec : Warning< def warn_cxx17_compat_decomp_decl_spec : Warning<
"decomposition declaration declared " "decomposition declaration declared "
"%plural{1:'%1'|:with '%1' specifiers}0 " "%plural{1:'%1'|:with '%1' specifiers}0 "
"is incompatible with C++ standards before C++2a">, "is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def err_decomp_decl_type : Error< def err_decomp_decl_type : Error<
"decomposition declaration cannot be declared with type %0; " "decomposition declaration cannot be declared with type %0; "
"declared type must be 'auto' or reference to 'auto'">; "declared type must be 'auto' or reference to 'auto'">;
@ -1996,7 +1996,7 @@ def err_init_list_bad_dest_type : Error<
"list">; "list">;
def warn_cxx2a_compat_aggregate_init_with_ctors : Warning< def warn_cxx2a_compat_aggregate_init_with_ctors : Warning<
"aggregate initialization of type %0 with user-declared constructors " "aggregate initialization of type %0 with user-declared constructors "
"is incompatible with C++2a">, DefaultIgnore, InGroup<CXX2aCompat>; "is incompatible with C++20">, DefaultIgnore, InGroup<CXX20Compat>;
def err_reference_bind_to_bitfield : Error< def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to " "%select{non-const|volatile}0 reference cannot bind to "
@ -2492,7 +2492,7 @@ def err_constexpr_redecl_mismatch : Error<
def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
def warn_cxx17_compat_constexpr_virtual : Warning< def warn_cxx17_compat_constexpr_virtual : Warning<
"virtual constexpr functions are incompatible with " "virtual constexpr functions are incompatible with "
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_constexpr_virtual_base : Error< def err_constexpr_virtual_base : Error<
"constexpr %select{member function|constructor}0 not allowed in " "constexpr %select{member function|constructor}0 not allowed in "
"%select{struct|interface|class}1 with virtual base " "%select{struct|interface|class}1 with virtual base "
@ -2518,11 +2518,11 @@ def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning<
InGroup<CXXPre14Compat>, DefaultIgnore; InGroup<CXXPre14Compat>, DefaultIgnore;
def ext_constexpr_body_invalid_stmt_cxx2a : ExtWarn< def ext_constexpr_body_invalid_stmt_cxx2a : ExtWarn<
"use of this statement in a constexpr %select{function|constructor}0 " "use of this statement in a constexpr %select{function|constructor}0 "
"is a C++2a extension">, InGroup<CXX2a>; "is a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning< def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning<
"use of this statement in a constexpr %select{function|constructor}0 " "use of this statement in a constexpr %select{function|constructor}0 "
"is incompatible with C++ standards before C++2a">, "is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_constexpr_type_definition : ExtWarn< def ext_constexpr_type_definition : ExtWarn<
"type definition in a constexpr %select{function|constructor}0 " "type definition in a constexpr %select{function|constructor}0 "
"is a C++14 extension">, InGroup<CXX14>; "is a C++14 extension">, InGroup<CXX14>;
@ -2548,11 +2548,11 @@ def err_constexpr_local_var_non_literal_type : Error<
"%select{function|constructor}0">; "%select{function|constructor}0">;
def ext_constexpr_local_var_no_init : ExtWarn< def ext_constexpr_local_var_no_init : ExtWarn<
"uninitialized variable in a constexpr %select{function|constructor}0 " "uninitialized variable in a constexpr %select{function|constructor}0 "
"is a C++20 extension">, InGroup<CXX2a>; "is a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_constexpr_local_var_no_init : Warning< def warn_cxx17_compat_constexpr_local_var_no_init : Warning<
"uninitialized variable in a constexpr %select{function|constructor}0 " "uninitialized variable in a constexpr %select{function|constructor}0 "
"is incompatible with C++ standards before C++20">, "is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_constexpr_function_never_constant_expr : ExtWarn< def ext_constexpr_function_never_constant_expr : ExtWarn<
"%select{constexpr|consteval}1 %select{function|constructor}0 never produces a " "%select{constexpr|consteval}1 %select{function|constructor}0 never produces a "
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError; "constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
@ -2578,29 +2578,29 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
def note_constexpr_body_previous_return : Note< def note_constexpr_body_previous_return : Note<
"previous return statement is here">; "previous return statement is here">;
// C++2a function try blocks in constexpr // C++20 function try blocks in constexpr
def ext_constexpr_function_try_block_cxx2a : ExtWarn< def ext_constexpr_function_try_block_cxx2a : ExtWarn<
"function try block in constexpr %select{function|constructor}0 is " "function try block in constexpr %select{function|constructor}0 is "
"a C++2a extension">, InGroup<CXX2a>; "a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_constexpr_function_try_block : Warning< def warn_cxx17_compat_constexpr_function_try_block : Warning<
"function try block in constexpr %select{function|constructor}0 is " "function try block in constexpr %select{function|constructor}0 is "
"incompatible with C++ standards before C++2a">, "incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_constexpr_union_ctor_no_init : ExtWarn< def ext_constexpr_union_ctor_no_init : ExtWarn<
"constexpr union constructor that does not initialize any member " "constexpr union constructor that does not initialize any member "
"is a C++20 extension">, InGroup<CXX2a>; "is a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning< def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning<
"constexpr union constructor that does not initialize any member " "constexpr union constructor that does not initialize any member "
"is incompatible with C++ standards before C++20">, "is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_constexpr_ctor_missing_init : ExtWarn< def ext_constexpr_ctor_missing_init : ExtWarn<
"constexpr constructor that does not initialize all members " "constexpr constructor that does not initialize all members "
"is a C++20 extension">, InGroup<CXX2a>; "is a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_constexpr_ctor_missing_init : Warning< def warn_cxx17_compat_constexpr_ctor_missing_init : Warning<
"constexpr constructor that does not initialize all members " "constexpr constructor that does not initialize all members "
"is incompatible with C++ standards before C++20">, "is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def note_constexpr_ctor_missing_init : Note< def note_constexpr_ctor_missing_init : Note<
"member not initialized by constructor">; "member not initialized by constructor">;
def note_non_literal_no_constexpr_ctors : Note< def note_non_literal_no_constexpr_ctors : Note<
@ -2732,7 +2732,7 @@ def warn_cxx98_compat_unicode_type : Warning<
InGroup<CXX98Compat>, DefaultIgnore; InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx17_compat_unicode_type : Warning< def warn_cxx17_compat_unicode_type : Warning<
"'char8_t' type specifier is incompatible with C++ standards before C++20">, "'char8_t' type specifier is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
// __make_integer_seq // __make_integer_seq
def err_integer_sequence_negative_length : Error< def err_integer_sequence_negative_length : Error<
@ -4349,11 +4349,11 @@ def err_template_tag_noparams : Error<
def warn_cxx17_compat_adl_only_template_id : Warning< def warn_cxx17_compat_adl_only_template_id : Warning<
"use of function template name with no prior function template " "use of function template name with no prior function template "
"declaration in function call with explicit template arguments " "declaration in function call with explicit template arguments "
"is incompatible with C++ standards before C++2a">, "is incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompat>, DefaultIgnore; InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_adl_only_template_id : ExtWarn< def ext_adl_only_template_id : ExtWarn<
"use of function template name with no prior declaration in function call " "use of function template name with no prior declaration in function call "
"with explicit template arguments is a C++2a extension">, InGroup<CXX2a>; "with explicit template arguments is a C++20 extension">, InGroup<CXX20>;
// C++ Template Argument Lists // C++ Template Argument Lists
def err_template_missing_args : Error< def err_template_missing_args : Error<
@ -4495,12 +4495,12 @@ def err_pointer_to_member_oper_value_classify: Error<
"pointer-to-member function type %0 can only be called on an " "pointer-to-member function type %0 can only be called on an "
"%select{rvalue|lvalue}1">; "%select{rvalue|lvalue}1">;
def ext_pointer_to_const_ref_member_on_rvalue : Extension< def ext_pointer_to_const_ref_member_on_rvalue : Extension<
"invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension">, "invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension">,
InGroup<CXX2a>, SFINAEFailure; InGroup<CXX20>, SFINAEFailure;
def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning< def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning<
"invoking a pointer to a 'const &' member function on an rvalue is " "invoking a pointer to a 'const &' member function on an rvalue is "
"incompatible with C++ standards before C++2a">, "incompatible with C++ standards before C++20">,
InGroup<CXXPre2aCompatPedantic>, DefaultIgnore; InGroup<CXXPre20CompatPedantic>, DefaultIgnore;
def ext_ms_deref_template_argument: ExtWarn< def ext_ms_deref_template_argument: ExtWarn<
"non-type template argument containing a dereference operation is a " "non-type template argument containing a dereference operation is a "
"Microsoft extension">, InGroup<MicrosoftTemplate>; "Microsoft extension">, InGroup<MicrosoftTemplate>;
@ -6249,7 +6249,7 @@ def err_array_init_utf8_string_into_char : Error<
"UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">; "UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">;
def warn_cxx2a_compat_utf8_string : Warning< def warn_cxx2a_compat_utf8_string : Warning<
"type of UTF-8 string literal will change from array of const char to " "type of UTF-8 string literal will change from array of const char to "
"array of const char8_t in C++2a">, InGroup<CXX2aCompat>, DefaultIgnore; "array of const char8_t in C++20">, InGroup<CXX20Compat>, DefaultIgnore;
def note_cxx2a_compat_utf8_string_remove_u8 : Note< def note_cxx2a_compat_utf8_string_remove_u8 : Note<
"remove 'u8' prefix to avoid a change of behavior; " "remove 'u8' prefix to avoid a change of behavior; "
"Clang encodes unprefixed narrow string literals as UTF-8">; "Clang encodes unprefixed narrow string literals as UTF-8">;
@ -7178,9 +7178,9 @@ let CategoryName = "Lambda Issue" in {
"cannot deduce type for lambda capture %0 from initializer list">; "cannot deduce type for lambda capture %0 from initializer list">;
def warn_cxx17_compat_init_capture_pack : Warning< def warn_cxx17_compat_init_capture_pack : Warning<
"initialized lambda capture packs are incompatible with C++ standards " "initialized lambda capture packs are incompatible with C++ standards "
"before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_init_capture_pack : ExtWarn< def ext_init_capture_pack : ExtWarn<
"initialized lambda pack captures are a C++2a extension">, InGroup<CXX2a>; "initialized lambda pack captures are a C++20 extension">, InGroup<CXX20>;
// C++14 generic lambdas. // C++14 generic lambdas.
def warn_cxx11_compat_generic_lambda : Warning< def warn_cxx11_compat_generic_lambda : Warning<
@ -7198,23 +7198,23 @@ let CategoryName = "Lambda Issue" in {
def err_parameter_shadow_capture : Error< def err_parameter_shadow_capture : Error<
"a lambda parameter cannot shadow an explicitly captured entity">; "a lambda parameter cannot shadow an explicitly captured entity">;
// C++2a [=, this] captures. // C++20 [=, this] captures.
def warn_cxx17_compat_equals_this_lambda_capture : Warning< def warn_cxx17_compat_equals_this_lambda_capture : Warning<
"explicit capture of 'this' with a capture default of '=' is incompatible " "explicit capture of 'this' with a capture default of '=' is incompatible "
"with C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "with C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_equals_this_lambda_capture_cxx2a : ExtWarn< def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
"explicit capture of 'this' with a capture default of '=' " "explicit capture of 'this' with a capture default of '=' "
"is a C++2a extension">, InGroup<CXX2a>; "is a C++20 extension">, InGroup<CXX20>;
def warn_deprecated_this_capture : Warning< def warn_deprecated_this_capture : Warning<
"implicit capture of 'this' with a capture default of '=' is deprecated">, "implicit capture of 'this' with a capture default of '=' is deprecated">,
InGroup<DeprecatedThisCapture>, DefaultIgnore; InGroup<DeprecatedThisCapture>, DefaultIgnore;
def note_deprecated_this_capture : Note< def note_deprecated_this_capture : Note<
"add an explicit capture of 'this' to capture '*this' by reference">; "add an explicit capture of 'this' to capture '*this' by reference">;
// C++2a default constructible / assignable lambdas. // C++20 default constructible / assignable lambdas.
def warn_cxx17_compat_lambda_def_ctor_assign : Warning< def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
"%select{default construction|assignment}0 of lambda is incompatible with " "%select{default construction|assignment}0 of lambda is incompatible with "
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
} }
def err_return_in_captured_stmt : Error< def err_return_in_captured_stmt : Error<
@ -7915,7 +7915,7 @@ def ext_cxx14_attr : Extension<
def ext_cxx17_attr : Extension< def ext_cxx17_attr : Extension<
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17>; "use of the %0 attribute is a C++17 extension">, InGroup<CXX17>;
def ext_cxx2a_attr : Extension< def ext_cxx2a_attr : Extension<
"use of the %0 attribute is a C++2a extension">, InGroup<CXX2a>; "use of the %0 attribute is a C++20 extension">, InGroup<CXX20>;
def warn_unused_comparison : Warning< def warn_unused_comparison : Warning<
"%select{equality|inequality|relational|three-way}0 comparison result unused">, "%select{equality|inequality|relational|three-way}0 comparison result unused">,
@ -7929,7 +7929,7 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
// C++20 constinit and require_constant_initialization attribute // C++20 constinit and require_constant_initialization attribute
def warn_cxx20_compat_constinit : Warning< def warn_cxx20_compat_constinit : Warning<
"'constinit' specifier is incompatible with C++ standards before C++20">, "'constinit' specifier is incompatible with C++ standards before C++20">,
InGroup<CXX2aCompat>, DefaultIgnore; InGroup<CXX20Compat>, DefaultIgnore;
def err_constinit_local_variable : Error< def err_constinit_local_variable : Error<
"local variable cannot be declared 'constinit'">; "local variable cannot be declared 'constinit'">;
def err_require_constant_init_failed : Error< def err_require_constant_init_failed : Error<
@ -8384,7 +8384,7 @@ def note_deleted_type_mismatch : Note<
def warn_cxx17_compat_defaulted_method_type_mismatch : Warning< def warn_cxx17_compat_defaulted_method_type_mismatch : Warning<
"explicitly defaulting this %sub{select_special_member_kind}0 with a type " "explicitly defaulting this %sub{select_special_member_kind}0 with a type "
"different from the implicit type is incompatible with C++ standards before " "different from the implicit type is incompatible with C++ standards before "
"C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; "C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def warn_vbase_moved_multiple_times : Warning< def warn_vbase_moved_multiple_times : Warning<
"defaulted move assignment operator of %0 will move assign virtual base " "defaulted move assignment operator of %0 will move assign virtual base "
"class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>; "class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>;
@ -8398,10 +8398,10 @@ def select_defaulted_comparison_kind : TextSubstitution<
"%select{<ERROR>|equality|three-way|equality|relational}0 comparison " "%select{<ERROR>|equality|three-way|equality|relational}0 comparison "
"operator">; "operator">;
def ext_defaulted_comparison : ExtWarn< def ext_defaulted_comparison : ExtWarn<
"defaulted comparison operators are a C++20 extension">, InGroup<CXX2a>; "defaulted comparison operators are a C++20 extension">, InGroup<CXX20>;
def warn_cxx17_compat_defaulted_comparison : Warning< def warn_cxx17_compat_defaulted_comparison : Warning<
"defaulted comparison operators are incompatible with C++ standards " "defaulted comparison operators are incompatible with C++ standards "
"before C++20">, InGroup<CXXPre2aCompat>, DefaultIgnore; "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_defaulted_comparison_template : Error< def err_defaulted_comparison_template : Error<
"comparison operator template cannot be defaulted">; "comparison operator template cannot be defaulted">;
def err_defaulted_comparison_out_of_class : Error< def err_defaulted_comparison_out_of_class : Error<

View File

@ -140,15 +140,17 @@ LANGSTANDARD(gnucxx17, "gnu++17",
Digraphs | HexFloat | GNUMode) Digraphs | HexFloat | GNUMode)
LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z") LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z")
LANGSTANDARD(cxx2a, "c++2a", LANGSTANDARD(cxx20, "c++20",
CXX, "Working draft for ISO C++ 2020", CXX, "ISO C++ 2020 DIS",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
CPlusPlus2a | Digraphs | HexFloat) CPlusPlus2a | Digraphs | HexFloat)
LANGSTANDARD_ALIAS_DEPR(cxx20, "c++2a")
LANGSTANDARD(gnucxx2a, "gnu++2a", LANGSTANDARD(gnucxx20, "gnu++20",
CXX, "Working draft for ISO C++ 2020 with GNU extensions", CXX, "ISO C++ 2020 DIS with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
CPlusPlus2a | Digraphs | HexFloat | GNUMode) CPlusPlus2a | Digraphs | HexFloat | GNUMode)
LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a")
// OpenCL // OpenCL
LANGSTANDARD(opencl10, "cl1.0", LANGSTANDARD(opencl10, "cl1.0",

View File

@ -162,7 +162,7 @@ def CoawaitExpr : StmtNode<CoroutineSuspendExpr>;
def DependentCoawaitExpr : StmtNode<Expr>; def DependentCoawaitExpr : StmtNode<Expr>;
def CoyieldExpr : StmtNode<CoroutineSuspendExpr>; def CoyieldExpr : StmtNode<CoroutineSuspendExpr>;
// C++2a Concepts expressions // C++20 Concepts expressions
def ConceptSpecializationExpr : StmtNode<Expr>; def ConceptSpecializationExpr : StmtNode<Expr>;
def RequiresExpr : StmtNode<Expr>; def RequiresExpr : StmtNode<Expr>;

View File

@ -344,13 +344,27 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
const LangOptions &LangOpts, const LangOptions &LangOpts,
const FrontendOptions &FEOpts, const FrontendOptions &FEOpts,
MacroBuilder &Builder) { MacroBuilder &Builder) {
// C++ [cpp.predefined]p1:
// The following macro names shall be defined by the implementation:
// -- __STDC__
// [C++] Whether __STDC__ is predefined and if so, what its value is,
// are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP) if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP)
Builder.defineMacro("__STDC__"); Builder.defineMacro("__STDC__");
// -- __STDC_HOSTED__
// The integer literal 1 if the implementation is a hosted
// implementation or the integer literal 0 if it is not.
if (LangOpts.Freestanding) if (LangOpts.Freestanding)
Builder.defineMacro("__STDC_HOSTED__", "0"); Builder.defineMacro("__STDC_HOSTED__", "0");
else else
Builder.defineMacro("__STDC_HOSTED__"); Builder.defineMacro("__STDC_HOSTED__");
// -- __STDC_VERSION__
// [C++] Whether __STDC_VERSION__ is predefined and if so, what its
// value is, are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.CPlusPlus) { if (!LangOpts.CPlusPlus) {
if (LangOpts.C17) if (LangOpts.C17)
Builder.defineMacro("__STDC_VERSION__", "201710L"); Builder.defineMacro("__STDC_VERSION__", "201710L");
@ -361,33 +375,29 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
else if (!LangOpts.GNUMode && LangOpts.Digraphs) else if (!LangOpts.GNUMode && LangOpts.Digraphs)
Builder.defineMacro("__STDC_VERSION__", "199409L"); Builder.defineMacro("__STDC_VERSION__", "199409L");
} else { } else {
// FIXME: Use correct value for C++20. // -- __cplusplus
// [C++20] The integer literal 202002L.
if (LangOpts.CPlusPlus2a) if (LangOpts.CPlusPlus2a)
Builder.defineMacro("__cplusplus", "201707L"); Builder.defineMacro("__cplusplus", "202002L");
// C++17 [cpp.predefined]p1: // [C++17] The integer literal 201703L.
// The name __cplusplus is defined to the value 201703L when compiling a
// C++ translation unit.
else if (LangOpts.CPlusPlus17) else if (LangOpts.CPlusPlus17)
Builder.defineMacro("__cplusplus", "201703L"); Builder.defineMacro("__cplusplus", "201703L");
// C++1y [cpp.predefined]p1: // [C++14] The name __cplusplus is defined to the value 201402L when
// The name __cplusplus is defined to the value 201402L when compiling a // compiling a C++ translation unit.
// C++ translation unit.
else if (LangOpts.CPlusPlus14) else if (LangOpts.CPlusPlus14)
Builder.defineMacro("__cplusplus", "201402L"); Builder.defineMacro("__cplusplus", "201402L");
// C++11 [cpp.predefined]p1: // [C++11] The name __cplusplus is defined to the value 201103L when
// The name __cplusplus is defined to the value 201103L when compiling a // compiling a C++ translation unit.
// C++ translation unit.
else if (LangOpts.CPlusPlus11) else if (LangOpts.CPlusPlus11)
Builder.defineMacro("__cplusplus", "201103L"); Builder.defineMacro("__cplusplus", "201103L");
// C++03 [cpp.predefined]p1: // [C++03] The name __cplusplus is defined to the value 199711L when
// The name __cplusplus is defined to the value 199711L when compiling a // compiling a C++ translation unit.
// C++ translation unit.
else else
Builder.defineMacro("__cplusplus", "199711L"); Builder.defineMacro("__cplusplus", "199711L");
// C++1z [cpp.predefined]p1: // -- __STDCPP_DEFAULT_NEW_ALIGNMENT__
// An integer literal of type std::size_t whose value is the alignment // [C++17] An integer literal of type std::size_t whose value is the
// guaranteed by a call to operator new(std::size_t) // alignment guaranteed by a call to operator new(std::size_t)
// //
// We provide this in all language modes, since it seems generally useful. // We provide this in all language modes, since it seems generally useful.
Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__", Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__",

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
typedef int fn; typedef int fn;
@ -43,7 +43,7 @@ namespace std_example {
int x = f<N::A>(N::A()); int x = f<N::A>(N::A());
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{C++2a extension}} // expected-warning@-2 {{C++20 extension}}
#endif #endif
int y = g<N::A>(N::A()); int y = g<N::A>(N::A());
#if __cplusplus <= 201703L #if __cplusplus <= 201703L

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++2a -verify -Wc++2a-extensions %s // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -Wc++20-extensions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -Wc++17-extensions %s // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -Wc++17-extensions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT -Wc++17-extensions -Wc++2a-extensions %s // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT -Wc++17-extensions -Wc++20-extensions %s
struct [[nodiscard]] S {}; struct [[nodiscard]] S {};
S get_s(); S get_s();
@ -73,7 +73,7 @@ LaterReason get_later_reason();
[[nodiscard("conflicting reason")]] int conflicting_reason(); [[nodiscard("conflicting reason")]] int conflicting_reason();
[[nodiscard("special reason")]] int conflicting_reason(); [[nodiscard("special reason")]] int conflicting_reason();
void cxx2a_use() { void cxx20_use() {
get_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: reason}} get_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: reason}}
get_later_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: later reason}} get_later_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: later reason}}
another_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: another reason}} another_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: another reason}}
@ -130,15 +130,15 @@ void usage() {
// expected-warning@12 {{use of the 'nodiscard' attribute is a C++17 extension}} // expected-warning@12 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@13 {{use of the 'nodiscard' attribute is a C++17 extension}} // expected-warning@13 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@29 {{use of the 'nodiscard' attribute is a C++17 extension}} // expected-warning@29 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@65 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@65 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@67 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@67 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@71 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@71 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@73 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@73 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@74 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@74 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@84 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@84 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@86 {{use of the 'nodiscard' attribute is a C++17 extension}} // expected-warning@86 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@87 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@87 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@91 {{use of the 'nodiscard' attribute is a C++17 extension}} // expected-warning@91 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@92 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@92 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@95 {{use of the 'nodiscard' attribute is a C++2a extension}} // expected-warning@95 {{use of the 'nodiscard' attribute is a C++20 extension}}
#endif #endif

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions -Werror=c++2a-extensions %s // RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++14-extensions -Werror=c++20-extensions %s
// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y -Werror=c++2a-extensions %s // RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++14 -DCXX14 -Werror=c++20-extensions %s
// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++2a -DCXX1Y -DCXX2A %s // RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++20 -DCXX14 -DCXX20 %s
namespace N { namespace N {
typedef char C; typedef char C;
@ -54,11 +54,11 @@ struct T : SS, NonLiteral {
// - its return type shall be a literal type; // - its return type shall be a literal type;
constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
constexpr void VoidReturn() const { return; } constexpr void VoidReturn() const { return; }
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{constexpr function's return type 'void' is not a literal type}} // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}}
#endif #endif
constexpr ~T(); constexpr ~T();
#ifndef CXX2A #ifndef CXX20
// expected-error@-2 {{destructor cannot be declared constexpr}} // expected-error@-2 {{destructor cannot be declared constexpr}}
#endif #endif
typedef NonLiteral F() const; typedef NonLiteral F() const;
@ -78,7 +78,7 @@ struct T : SS, NonLiteral {
// don't have a literal return type. Defaulted assignment operators can't be // don't have a literal return type. Defaulted assignment operators can't be
// constexpr since they can't be const. // constexpr since they can't be const.
constexpr T &operator=(const T&) = default; constexpr T &operator=(const T&) = default;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
// expected-warning@-3 {{C++14}} // expected-warning@-3 {{C++14}}
#else #else
@ -87,14 +87,14 @@ struct T : SS, NonLiteral {
}; };
constexpr int T::OutOfLineVirtual() const { return 0; } constexpr int T::OutOfLineVirtual() const { return 0; }
#ifdef CXX1Y #ifdef CXX14
struct T2 { struct T2 {
int n = 0; int n = 0;
constexpr T2 &operator=(const T2&) = default; // ok constexpr T2 &operator=(const T2&) = default; // ok
}; };
struct T3 { struct T3 {
constexpr T3 &operator=(const T3&) const = default; constexpr T3 &operator=(const T3&) const = default;
#ifndef CXX2A #ifndef CXX20
// expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
#else #else
// expected-warning@-4 {{explicitly defaulted copy assignment operator is implicitly deleted}} // expected-warning@-4 {{explicitly defaulted copy assignment operator is implicitly deleted}}
@ -138,56 +138,56 @@ constexpr int AllowedStmtsCXX11() {
return sizeof(K) + sizeof(C) + sizeof(K); return sizeof(K) + sizeof(C) + sizeof(K);
} }
// or a compound-statement that does not contain [CXX1Y] // or a compound-statement that does not contain [C++14]
constexpr int DisallowedStmtsCXX1Y_1(bool b) { constexpr int DisallowedStmtsCXX14_1(bool b) {
// - an asm-definition // - an asm-definition
if (b) if (b)
asm("int3"); asm("int3");
#if !defined(CXX2A) #if !defined(CXX20)
// expected-error@-2 {{use of this statement in a constexpr function is a C++2a extension}} // expected-error@-2 {{use of this statement in a constexpr function is a C++20 extension}}
#endif #endif
return 0; return 0;
} }
constexpr int DisallowedStmtsCXX1Y_2() { constexpr int DisallowedStmtsCXX14_2() {
// - a goto statement // - a goto statement
goto x; // expected-error {{statement not allowed in constexpr function}} goto x; // expected-error {{statement not allowed in constexpr function}}
x: x:
return 0; return 0;
} }
constexpr int DisallowedStmtsCXX1Y_2_1() { constexpr int DisallowedStmtsCXX14_2_1() {
try { try {
return 0; return 0;
} catch (...) { } catch (...) {
merp: goto merp; // expected-error {{statement not allowed in constexpr function}} merp: goto merp; // expected-error {{statement not allowed in constexpr function}}
} }
} }
constexpr int DisallowedStmtsCXX1Y_3() { constexpr int DisallowedStmtsCXX14_3() {
// - a try-block, // - a try-block,
try {} catch (...) {} try {} catch (...) {}
#if !defined(CXX2A) #if !defined(CXX20)
// expected-error@-2 {{use of this statement in a constexpr function is a C++2a extension}} // expected-error@-2 {{use of this statement in a constexpr function is a C++20 extension}}
#endif #endif
return 0; return 0;
} }
constexpr int DisallowedStmtsCXX1Y_4() { constexpr int DisallowedStmtsCXX14_4() {
// - a definition of a variable of non-literal type // - a definition of a variable of non-literal type
NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}} NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}}
return 0; return 0;
} }
constexpr int DisallowedStmtsCXX1Y_5() { constexpr int DisallowedStmtsCXX14_5() {
// - a definition of a variable of static storage duration // - a definition of a variable of static storage duration
static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}} static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}}
return n; return n;
} }
constexpr int DisallowedStmtsCXX1Y_6() { constexpr int DisallowedStmtsCXX14_6() {
// - a definition of a variable of thread storage duration // - a definition of a variable of thread storage duration
thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}} thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}}
return n; return n;
} }
constexpr int DisallowedStmtsCXX1Y_7() { constexpr int DisallowedStmtsCXX14_7() {
// - a definition of a variable for which no initialization is performed // - a definition of a variable for which no initialization is performed
int n; int n;
#ifndef CXX2A #ifndef CXX20
// expected-error@-2 {{uninitialized variable in a constexpr function}} // expected-error@-2 {{uninitialized variable in a constexpr function}}
#endif #endif
return 0; return 0;
@ -195,28 +195,28 @@ constexpr int DisallowedStmtsCXX1Y_7() {
constexpr int ForStmt() { constexpr int ForStmt() {
for (int n = 0; n < 10; ++n) for (int n = 0; n < 10; ++n)
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{statement not allowed in constexpr function}} // expected-error@-2 {{statement not allowed in constexpr function}}
#endif #endif
return 0; return 0;
} }
constexpr int VarDecl() { constexpr int VarDecl() {
int a = 0; int a = 0;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
#endif #endif
return 0; return 0;
} }
constexpr int ConstexprVarDecl() { constexpr int ConstexprVarDecl() {
constexpr int a = 0; constexpr int a = 0;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
#endif #endif
return 0; return 0;
} }
constexpr int VarWithCtorDecl() { constexpr int VarWithCtorDecl() {
Literal a; Literal a;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
#endif #endif
return 0; return 0;
@ -224,7 +224,7 @@ constexpr int VarWithCtorDecl() {
NonLiteral nl; NonLiteral nl;
constexpr NonLiteral &ExternNonLiteralVarDecl() { constexpr NonLiteral &ExternNonLiteralVarDecl() {
extern NonLiteral nl; extern NonLiteral nl;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
#endif #endif
return nl; return nl;
@ -232,28 +232,28 @@ constexpr NonLiteral &ExternNonLiteralVarDecl() {
static_assert(&ExternNonLiteralVarDecl() == &nl, ""); static_assert(&ExternNonLiteralVarDecl() == &nl, "");
constexpr int FuncDecl() { constexpr int FuncDecl() {
constexpr int ForwardDecl(int); constexpr int ForwardDecl(int);
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{use of this statement in a constexpr function is a C++14 extension}} // expected-error@-2 {{use of this statement in a constexpr function is a C++14 extension}}
#endif #endif
return ForwardDecl(42); return ForwardDecl(42);
} }
constexpr int ClassDecl1() { constexpr int ClassDecl1() {
typedef struct { } S1; typedef struct { } S1;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
#endif #endif
return 0; return 0;
} }
constexpr int ClassDecl2() { constexpr int ClassDecl2() {
using S2 = struct { }; using S2 = struct { };
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
#endif #endif
return 0; return 0;
} }
constexpr int ClassDecl3() { constexpr int ClassDecl3() {
struct S3 { }; struct S3 { };
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
#endif #endif
return 0; return 0;
@ -262,7 +262,7 @@ constexpr int NoReturn() {} // expected-error {{no return statement in constexpr
constexpr int MultiReturn() { constexpr int MultiReturn() {
return 0; return 0;
return 0; return 0;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{multiple return statements in constexpr function}} // expected-error@-2 {{multiple return statements in constexpr function}}
// expected-note@-4 {{return statement}} // expected-note@-4 {{return statement}}
#endif #endif
@ -310,7 +310,7 @@ namespace std_example {
} }
constexpr int abs(int x) { constexpr int abs(int x) {
if (x < 0) if (x < 0)
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{C++14}} // expected-error@-2 {{C++14}}
#endif #endif
x = -x; x = -x;
@ -322,7 +322,7 @@ namespace std_example {
} }
constexpr int uninit() { constexpr int uninit() {
int a; int a;
#ifndef CXX2A #ifndef CXX20
// expected-error@-2 {{uninitialized}} // expected-error@-2 {{uninitialized}}
#endif #endif
return a; return a;
@ -330,7 +330,7 @@ namespace std_example {
constexpr int prev(int x) { constexpr int prev(int x) {
return --x; return --x;
} }
#ifndef CXX1Y #ifndef CXX14
// expected-error@-4 {{never produces a constant expression}} // expected-error@-4 {{never produces a constant expression}}
// expected-note@-4 {{subexpression}} // expected-note@-4 {{subexpression}}
#endif #endif
@ -339,7 +339,7 @@ namespace std_example {
while (--n > 0) r *= x; while (--n > 0) r *= x;
return r; return r;
} }
#ifndef CXX1Y #ifndef CXX14
// expected-error@-5 {{C++14}} // expected-error@-5 {{C++14}}
// expected-error@-5 {{statement not allowed}} // expected-error@-5 {{statement not allowed}}
#endif #endif

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions -Werror=c++2a-extensions %s // RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++14-extensions -Werror=c++20-extensions %s
// RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y -Werror=c++2a-extensions %s // RUN: %clang_cc1 -verify -std=c++14 -fcxx-exceptions -DCXX14 -Werror=c++20-extensions %s
// RUN: %clang_cc1 -verify -std=c++2a -fcxx-exceptions -DCXX1Y -DCXX2A %s // RUN: %clang_cc1 -verify -std=c++20 -fcxx-exceptions -DCXX14 -DCXX2A %s
namespace N { namespace N {
typedef char C; typedef char C;
@ -52,10 +52,10 @@ struct U {
constexpr U() constexpr U()
try try
#ifndef CXX2A #ifndef CXX2A
// expected-error@-2 {{function try block in constexpr constructor is a C++2a extension}} // expected-error@-2 {{function try block in constexpr constructor is a C++20 extension}}
#endif #endif
: u() { : u() {
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}
#endif #endif
} catch (...) { } catch (...) {
@ -92,43 +92,43 @@ struct V {
constexpr V(int(&)[1]) { constexpr V(int(&)[1]) {
for (int n = 0; n < 10; ++n) for (int n = 0; n < 10; ++n)
/**/; /**/;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-3 {{statement not allowed in constexpr constructor}} // expected-error@-3 {{statement not allowed in constexpr constructor}}
#endif #endif
} }
constexpr V(int(&)[2]) { constexpr V(int(&)[2]) {
constexpr int a = 0; constexpr int a = 0;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{variable declaration in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{variable declaration in a constexpr constructor is a C++14 extension}}
#endif #endif
} }
constexpr V(int(&)[3]) { constexpr V(int(&)[3]) {
constexpr int ForwardDecl(int); constexpr int ForwardDecl(int);
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}
#endif #endif
} }
constexpr V(int(&)[4]) { constexpr V(int(&)[4]) {
typedef struct { } S1; typedef struct { } S1;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}
#endif #endif
} }
constexpr V(int(&)[5]) { constexpr V(int(&)[5]) {
using S2 = struct { }; using S2 = struct { };
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}
#endif #endif
} }
constexpr V(int(&)[6]) { constexpr V(int(&)[6]) {
struct S3 { }; struct S3 { };
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}
#endif #endif
} }
constexpr V(int(&)[7]) { constexpr V(int(&)[7]) {
return; return;
#ifndef CXX1Y #ifndef CXX14
// expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}
#endif #endif
} }

View File

@ -1,10 +1,10 @@
// RUN: %clang_cc1 -verify=expected,pre2a %s -std=c++11 // RUN: %clang_cc1 -verify=expected,pre20 %s -std=c++11
// RUN: %clang_cc1 -verify=expected,pre2a %s -std=c++17 // RUN: %clang_cc1 -verify=expected,pre20 %s -std=c++17
// RUN: %clang_cc1 -verify=expected %s -std=c++2a // RUN: %clang_cc1 -verify=expected %s -std=c++20
// A function that is explicitly defaulted shall // A function that is explicitly defaulted shall
struct A { struct A {
// -- be a special member function [C++2a: or a comparison operator function], // -- be a special member function [C++20: or a comparison operator function],
A(int) = default; A(int) = default;
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{only special member functions may be defaulted}} // expected-error@-2 {{only special member functions may be defaulted}}
@ -14,13 +14,13 @@ struct A {
A(A) = default; // expected-error {{must pass its first argument by reference}} A(A) = default; // expected-error {{must pass its first argument by reference}}
void f(A) = default; // expected-error-re {{only special member functions{{( and comparison operators)?}} may be defaulted}} void f(A) = default; // expected-error-re {{only special member functions{{( and comparison operators)?}} may be defaulted}}
bool operator==(const A&) const = default; // pre2a-warning {{defaulted comparison operators are a C++20 extension}} bool operator==(const A&) const = default; // pre20-warning {{defaulted comparison operators are a C++20 extension}}
bool operator!=(const A&) const = default; // pre2a-warning {{defaulted comparison operators are a C++20 extension}} bool operator!=(const A&) const = default; // pre20-warning {{defaulted comparison operators are a C++20 extension}}
bool operator<(const A&) const = default; // pre2a-error {{only special member functions may be defaulted}} bool operator<(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
bool operator>(const A&) const = default; // pre2a-error {{only special member functions may be defaulted}} bool operator>(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
bool operator<=(const A&) const = default; // pre2a-error {{only special member functions may be defaulted}} bool operator<=(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
bool operator>=(const A&) const = default; // pre2a-error {{only special member functions may be defaulted}} bool operator>=(const A&) const = default; // pre20-error {{only special member functions may be defaulted}}
bool operator<=>(const A&) const = default; // pre2a-error 1+{{}} pre2a-warning {{'<=>' is a single token in C++2a}} bool operator<=>(const A&) const = default; // pre20-error 1+{{}} pre20-warning {{'<=>' is a single token in C++20}}
A operator+(const A&) const = default; // expected-error-re {{only special member functions{{( and comparison operators)?}} may be defaulted}} A operator+(const A&) const = default; // expected-error-re {{only special member functions{{( and comparison operators)?}} may be defaulted}}

View File

@ -2,7 +2,7 @@
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// PR13819 -- __SIZE_TYPE__ is incompatible. // PR13819 -- __SIZE_TYPE__ is incompatible.
typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}} typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}}
@ -449,8 +449,8 @@ namespace dr241 { // dr241: yes
template <class T> void g(T t); // expected-note {{candidate}} template <class T> void g(T t); // expected-note {{candidate}}
} }
void h(A::B b) { void h(A::B b) {
f<3>(b); // expected-error 0-1{{C++2a extension}} expected-error {{no matching}} f<3>(b); // expected-error 0-1{{C++20 extension}} expected-error {{no matching}}
g<3>(b); // expected-error 0-1{{C++2a extension}} g<3>(b); // expected-error 0-1{{C++20 extension}}
A::f<3>(b); // expected-error {{no matching}} A::f<3>(b); // expected-error {{no matching}}
A::g<3>(b); A::g<3>(b);
C::f<3>(b); // expected-error {{no matching}} C::f<3>(b); // expected-error {{no matching}}

View File

@ -2,7 +2,7 @@
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking
// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking // RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking
// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking // RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking
namespace std { namespace std {
struct type_info {}; struct type_info {};
@ -506,7 +506,7 @@ namespace dr647 { // dr647: yes
constexpr C(NonLiteral, int) {} // expected-error {{not a literal type}} constexpr C(NonLiteral, int) {} // expected-error {{not a literal type}}
constexpr C() try {} catch (...) {} constexpr C() try {} catch (...) {}
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{function try block in constexpr constructor is a C++2a extension}} // expected-error@-2 {{function try block in constexpr constructor is a C++20 extension}}
#endif #endif
#if __cplusplus < 201402L #if __cplusplus < 201402L
// expected-error@-5 {{use of this statement in a constexpr constructor is a C++14 extension}} // expected-error@-5 {{use of this statement in a constexpr constructor is a C++14 extension}}
@ -1070,7 +1070,7 @@ namespace dr687 { // dr687 (9 c++20, but the issue is still considered open)
// This is valid in C++20. // This is valid in C++20.
g<int>(a); g<int>(a);
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{C++2a extension}} // expected-error@-2 {{C++20 extension}}
#endif #endif
// This is not. // This is not.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -std=c++11 %s -verify -Wno-c++1y-extensions // RUN: %clang_cc1 -std=c++11 %s -verify -Wno-c++14-extensions
class X0 { class X0 {
void explicit_capture() { void explicit_capture() {
@ -8,7 +8,7 @@ class X0 {
(void)[this, this] () {}; // expected-error {{'this' can appear only once}} (void)[this, this] () {}; // expected-error {{'this' can appear only once}}
(void)[=, foo] () {}; // expected-error {{'&' must precede a capture when}} (void)[=, foo] () {}; // expected-error {{'&' must precede a capture when}}
(void)[=, &foo] () {}; (void)[=, &foo] () {};
(void)[=, this] () {}; // expected-warning {{C++2a extension}} (void)[=, this] () {}; // expected-warning {{C++20 extension}}
(void)[&, foo] () {}; (void)[&, foo] () {};
(void)[&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}} (void)[&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}}
(void)[&, this] () {}; (void)[&, this] () {};
@ -23,7 +23,7 @@ struct S2 {
void S2::f(int i) { void S2::f(int i) {
(void)[&, i]{ }; (void)[&, i]{ };
(void)[&, &i]{ }; // expected-error{{'&' cannot precede a capture when the capture default is '&'}} (void)[&, &i]{ }; // expected-error{{'&' cannot precede a capture when the capture default is '&'}}
(void)[=, this]{ }; // expected-warning{{C++2a extension}} (void)[=, this]{ }; // expected-warning{{C++20 extension}}
(void)[=]{ this->g(i); }; (void)[=]{ this->g(i); };
(void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}} (void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[i(0), i(1)]{ }; // expected-error{{'i' can appear only once in a capture list}} (void)[i(0), i(1)]{ }; // expected-error{{'i' can appear only once in a capture list}}

View File

@ -15,8 +15,8 @@
// CHECK-NEXT: note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard // CHECK-NEXT: note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
// CHECK-NEXT: note: use 'c++17' for 'ISO C++ 2017 with amendments' standard // CHECK-NEXT: note: use 'c++17' for 'ISO C++ 2017 with amendments' standard
// CHECK-NEXT: note: use 'gnu++17' for 'ISO C++ 2017 with amendments and GNU extensions' standard // CHECK-NEXT: note: use 'gnu++17' for 'ISO C++ 2017 with amendments and GNU extensions' standard
// CHECK-NEXT: note: use 'c++2a' for 'Working draft for ISO C++ 2020' standard // CHECK-NEXT: note: use 'c++20' for 'ISO C++ 2020 DIS' standard
// CHECK-NEXT: note: use 'gnu++2a' for 'Working draft for ISO C++ 2020 with GNU extensions' standard // CHECK-NEXT: note: use 'gnu++20' for 'ISO C++ 2020 DIS with GNU extensions' standard
// CUDA-NEXT: note: use 'cuda' for 'NVIDIA CUDA(tm)' standard // CUDA-NEXT: note: use 'cuda' for 'NVIDIA CUDA(tm)' standard
// Make sure that no other output is present. // Make sure that no other output is present.

View File

@ -1,9 +1,9 @@
// RUN: %clang_cc1 -std=c++17 %s -verify // RUN: %clang_cc1 -std=c++17 %s -verify
// RUN: %clang_cc1 -std=c++2a %s -verify // RUN: %clang_cc1 -std=c++20 %s -verify
// RUN: %clang_cc1 -std=c++2a %s -verify -Wc++17-compat -DCOMPAT // RUN: %clang_cc1 -std=c++20 %s -verify -Wc++17-compat -DCOMPAT
// //
// RUN: %clang_cc1 -std=c++17 %s -E -o - | FileCheck %s --check-prefix=CXX17 // RUN: %clang_cc1 -std=c++17 %s -E -o - | FileCheck %s --check-prefix=CXX17
// RUN: %clang_cc1 -std=c++2a %s -E -o - | FileCheck %s --check-prefix=CXX20 // RUN: %clang_cc1 -std=c++20 %s -E -o - | FileCheck %s --check-prefix=CXX20
namespace N { namespace N {
@ -12,19 +12,19 @@ void operator<=(A, A);
#if __cplusplus > 201703L #if __cplusplus > 201703L
void operator<=>(A, A); void operator<=>(A, A);
#ifdef COMPAT #ifdef COMPAT
// expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++2a}} // expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++20}}
#endif #endif
#endif #endif
template<auto> struct X {}; template<auto> struct X {};
X<operator<=> X<operator<=>
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{'<=>' is a single token in C++2a; add a space to avoid a change in behavior}} // expected-warning@-2 {{'<=>' is a single token in C++20; add a space to avoid a change in behavior}}
#else #else
> >
#endif #endif
#ifdef COMPAT #ifdef COMPAT
// expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++2a}} // expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++20}}
#endif #endif
x; x;
} }

View File

@ -1,15 +1,15 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -Wc++2a-compat -std=c++17 // RUN: %clang_cc1 %s -verify -fsyntax-only -Wc++20-compat -std=c++17
#define concept constexpr bool #define concept constexpr bool
template<typename T> template<typename T>
concept x = 0; concept x = 0;
#undef concept #undef concept
int co_await = 0; // expected-warning {{'co_await' is a keyword in C++2a}} int co_await = 0; // expected-warning {{'co_await' is a keyword in C++20}}
int co_return = 0; // expected-warning {{'co_return' is a keyword in C++2a}} int co_return = 0; // expected-warning {{'co_return' is a keyword in C++20}}
int co_yield = 0; // expected-warning {{'co_yield' is a keyword in C++2a}} int co_yield = 0; // expected-warning {{'co_yield' is a keyword in C++20}}
int char8_t = 0; // expected-warning {{'char8_t' is a keyword in C++2a}} int char8_t = 0; // expected-warning {{'char8_t' is a keyword in C++20}}
int concept = 0; // expected-warning {{'concept' is a keyword in C++2a}} int concept = 0; // expected-warning {{'concept' is a keyword in C++20}}
int requires = 0; // expected-warning {{'requires' is a keyword in C++2a}} int requires = 0; // expected-warning {{'requires' is a keyword in C++20}}
int consteval = 0; // expected-warning {{'consteval' is a keyword in C++2a}} int consteval = 0; // expected-warning {{'consteval' is a keyword in C++20}}
int constinit = 0; // expected-warning {{'constinit' is a keyword in C++2a}} int constinit = 0; // expected-warning {{'constinit' is a keyword in C++20}}

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c++1z %s -verify -fcxx-exceptions // RUN: %clang_cc1 -std=c++17 %s -verify -fcxx-exceptions
// RUN: not %clang_cc1 -std=c++1z %s -emit-llvm-only -fcxx-exceptions // RUN: not %clang_cc1 -std=c++17 %s -emit-llvm-only -fcxx-exceptions
struct S { int a, b, c; }; struct S { int a, b, c; };
@ -67,8 +67,8 @@ namespace BadSpecifiers {
struct S { int n; } s; struct S { int n; } s;
void f() { void f() {
// storage-class-specifiers // storage-class-specifiers
static auto &[a] = n; // expected-warning {{declared 'static' is a C++2a extension}} static auto &[a] = n; // expected-warning {{declared 'static' is a C++20 extension}}
thread_local auto &[b] = n; // expected-warning {{declared 'thread_local' is a C++2a extension}} thread_local auto &[b] = n; // expected-warning {{declared 'thread_local' is a C++20 extension}}
extern auto &[c] = n; // expected-error {{cannot be declared 'extern'}} expected-error {{cannot have an initializer}} extern auto &[c] = n; // expected-error {{cannot be declared 'extern'}} expected-error {{cannot have an initializer}}
struct S { struct S {
mutable auto &[d] = n; // expected-error {{not permitted in this context}} mutable auto &[d] = n; // expected-error {{not permitted in this context}}
@ -85,7 +85,7 @@ namespace BadSpecifiers {
} }
static constexpr inline thread_local auto &[j1] = n; // expected-error {{cannot be declared with 'constexpr inline' specifiers}} static constexpr inline thread_local auto &[j1] = n; // expected-error {{cannot be declared with 'constexpr inline' specifiers}}
static thread_local auto &[j2] = n; // expected-warning {{declared with 'static thread_local' specifiers is a C++2a extension}} static thread_local auto &[j2] = n; // expected-warning {{declared with 'static thread_local' specifiers is a C++20 extension}}
inline auto &[k] = n; // expected-error {{cannot be declared 'inline'}} inline auto &[k] = n; // expected-error {{cannot be declared 'inline'}}

View File

@ -1,6 +1,6 @@
// Support parsing of concepts // Support parsing of concepts
// RUN: %clang_cc1 -std=c++2a -verify %s // RUN: %clang_cc1 -std=c++20 -verify %s
template<typename T> concept C1 = true; // expected-note 2{{previous}} template<typename T> concept C1 = true; // expected-note 2{{previous}}
template<typename T> concept C1 = true; // expected-error{{redefinition}} template<typename T> concept C1 = true; // expected-error{{redefinition}}
@ -50,7 +50,7 @@ template <bool word> concept C6 = integral_constant<bool, wor>::value;
// expected-note@-2{{'word' declared here}} // expected-note@-2{{'word' declared here}}
template<typename T> concept bool C7 = true; template<typename T> concept bool C7 = true;
// expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}} // expected-warning@-1{{ISO C++20 does not permit the 'bool' keyword after 'concept'}}
template<> concept C8 = false; template<> concept C8 = false;
// expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}} // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}

View File

@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++2a -Wc++17-compat // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -Wc++17-compat
namespace inline foo1::foo2::foo3 { // expected-error {{expected identifier or '{'}} expected-error {{use of undeclared identifier 'foo1'}} namespace inline foo1::foo2::foo3 { // expected-error {{expected identifier or '{'}} expected-error {{use of undeclared identifier 'foo1'}}
} }
@ -10,11 +10,11 @@ inline namespace foo4::foo5::foo6 { // expected-error {{nested namespace definit
#if __cplusplus <= 201402L #if __cplusplus <= 201402L
// expected-warning@+7 {{nested namespace definition is a C++17 extension; define each namespace separately}} // expected-warning@+7 {{nested namespace definition is a C++17 extension; define each namespace separately}}
// expected-warning@+6 {{inline nested namespace definition is a C++2a extension}} // expected-warning@+6 {{inline nested namespace definition is a C++20 extension}}
#elif __cplusplus <= 201703L #elif __cplusplus <= 201703L
// expected-warning@+4 {{inline nested namespace definition is a C++2a extension}} // expected-warning@+4 {{inline nested namespace definition is a C++20 extension}}
#else #else
// expected-warning@+2 {{inline nested namespace definition is incompatible with C++ standards before C++2a}} // expected-warning@+2 {{inline nested namespace definition is incompatible with C++ standards before C++20}}
#endif #endif
namespace valid1::valid2::inline valid3::inline valid4::valid5 {} namespace valid1::valid2::inline valid3::inline valid4::valid5 {}
// expected-note@-1 2 {{previous definition is here}} // expected-note@-1 2 {{previous definition is here}}
@ -27,11 +27,11 @@ namespace valid1::valid2::valid3::valid4::valid5 {}
#if __cplusplus <= 201402L #if __cplusplus <= 201402L
// expected-warning@+7 {{nested namespace definition is a C++17 extension; define each namespace separately}} // expected-warning@+7 {{nested namespace definition is a C++17 extension; define each namespace separately}}
// expected-warning@+6 {{inline nested namespace definition is a C++2a extension}} // expected-warning@+6 {{inline nested namespace definition is a C++20 extension}}
#elif __cplusplus <= 201703L #elif __cplusplus <= 201703L
// expected-warning@+4 {{inline nested namespace definition is a C++2a extension}} // expected-warning@+4 {{inline nested namespace definition is a C++20 extension}}
#else #else
// expected-warning@+2 {{inline nested namespace definition is incompatible with C++ standards before C++2a}} // expected-warning@+2 {{inline nested namespace definition is incompatible with C++ standards before C++20}}
#endif #endif
namespace valid1::valid2::inline valid3::inline valid4::valid5 {} namespace valid1::valid2::inline valid3::inline valid4::valid5 {}
// expected-note@-1 2 {{previous definition is here}} // expected-note@-1 2 {{previous definition is here}}

View File

@ -1,18 +1,18 @@
// RUN: %clang_cc1 -std=c++17 -verify=cxx17 -Wc++2a-compat %s // RUN: %clang_cc1 -std=c++17 -verify=cxx17 -Wc++20-compat %s
// RUN: %clang_cc1 -std=c++2a -verify=cxx2a -Wc++17-compat %s // RUN: %clang_cc1 -std=c++20 -verify=cxx20 -Wc++17-compat %s
namespace disambig { namespace disambig {
// Cases that are valid in C++17 and before, ill-formed in C++20, and that we // Cases that are valid in C++17 and before, ill-formed in C++20, and that we
// should not treat as explicit(bool) as an extension. // should not treat as explicit(bool) as an extension.
struct A { // cxx2a-note +{{}} struct A { // cxx20-note +{{}}
constexpr A() {} constexpr A() {}
constexpr operator bool() { return true; } constexpr operator bool() { return true; }
constexpr explicit (A)(int); // #1 constexpr explicit (A)(int); // #1
// cxx17-warning@#1 {{will be parsed as explicit(bool)}} // cxx17-warning@#1 {{will be parsed as explicit(bool)}}
// cxx2a-error@#1 +{{}} cxx2a-note@#1 +{{}} // cxx20-error@#1 +{{}} cxx20-note@#1 +{{}}
// cxx2a-warning@#1 {{incompatible with C++ standards before C++2a}} // cxx20-warning@#1 {{incompatible with C++ standards before C++20}}
// This is ill-formed (via a DR change), and shouldn't be recognized as a // This is ill-formed (via a DR change), and shouldn't be recognized as a
// constructor (the function declarator cannot be parenthesized in a // constructor (the function declarator cannot be parenthesized in a
@ -21,19 +21,19 @@ struct A { // cxx2a-note +{{}}
// FIXME: Produce an ExtWarn for this. // FIXME: Produce an ExtWarn for this.
constexpr explicit (A(float)); // #1b constexpr explicit (A(float)); // #1b
// cxx17-warning@#1b {{will be parsed as explicit(bool)}} // cxx17-warning@#1b {{will be parsed as explicit(bool)}}
// cxx2a-error@#1b +{{}} // cxx20-error@#1b +{{}}
// cxx2a-warning@#1b {{incompatible with C++ standards before C++2a}} // cxx20-warning@#1b {{incompatible with C++ standards before C++20}}
explicit (operator int)(); // #2 explicit (operator int)(); // #2
// cxx17-warning@#2 {{will be parsed as explicit(bool)}} // cxx17-warning@#2 {{will be parsed as explicit(bool)}}
// cxx2a-error@#2 +{{}} // cxx20-error@#2 +{{}}
// cxx2a-warning@#2 {{incompatible with C++ standards before C++2a}} // cxx20-warning@#2 {{incompatible with C++ standards before C++20}}
explicit (A::operator float)(); // #2b explicit (A::operator float)(); // #2b
// cxx17-warning@#2b {{will be parsed as explicit(bool)}} // cxx17-warning@#2b {{will be parsed as explicit(bool)}}
// cxx17-error@#2b {{extra qualification on member}} // cxx17-error@#2b {{extra qualification on member}}
// cxx2a-error@#2b +{{}} // cxx20-error@#2b +{{}}
// cxx2a-warning@#2b {{incompatible with C++ standards before C++2a}} // cxx20-warning@#2b {{incompatible with C++ standards before C++20}}
}; };
constexpr bool operator+(A) { return true; } constexpr bool operator+(A) { return true; }
@ -45,18 +45,18 @@ constexpr bool C = false;
struct B { struct B {
// Looks like a constructor, but not the constructor of B. // Looks like a constructor, but not the constructor of B.
explicit (A()) B(); // #3 explicit (A()) B(); // #3
// cxx17-warning@#3 {{C++2a extension}} // cxx17-warning@#3 {{C++20 extension}}
// cxx2a-warning@#3 {{incompatible with C++ standards before C++2a}} // cxx20-warning@#3 {{incompatible with C++ standards before C++20}}
// Looks like a 'constructor' of C. Actually a constructor of B. // Looks like a 'constructor' of C. Actually a constructor of B.
explicit (C)(B)(A); // #4 explicit (C)(B)(A); // #4
// cxx17-warning@#4 {{C++2a extension}} // cxx17-warning@#4 {{C++20 extension}}
// cxx2a-warning@#4 {{incompatible with C++ standards before C++2a}} // cxx20-warning@#4 {{incompatible with C++ standards before C++20}}
explicit (operator+(A())) operator int(); // #5 explicit (operator+(A())) operator int(); // #5
// cxx17-error@#5 {{requires a type specifier}} cxx17-error@#5 {{expected ';'}} // cxx17-error@#5 {{requires a type specifier}} cxx17-error@#5 {{expected ';'}}
// cxx17-warning@#5 {{will be parsed as explicit(bool)}} // cxx17-warning@#5 {{will be parsed as explicit(bool)}}
// cxx2a-warning@#5 {{incompatible with C++ standards before C++2a}} // cxx20-warning@#5 {{incompatible with C++ standards before C++20}}
}; };
} }

View File

@ -9,15 +9,17 @@
// BLOCKS:#define __block __attribute__((__blocks__(byref))) // BLOCKS:#define __block __attribute__((__blocks__(byref)))
// //
// //
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++20 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2A %s
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2A %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2A %s
// //
// CXX2A:#define __GNUG__ 4 // CXX2A:#define __GNUG__ 4
// CXX2A:#define __GXX_EXPERIMENTAL_CXX0X__ 1 // CXX2A:#define __GXX_EXPERIMENTAL_CXX0X__ 1
// CXX2A:#define __GXX_RTTI 1 // CXX2A:#define __GXX_RTTI 1
// CXX2A:#define __GXX_WEAK__ 1 // CXX2A:#define __GXX_WEAK__ 1
// CXX2A:#define __cplusplus 201707L // CXX2A:#define __cplusplus 202002L
// CXX2A:#define __private_extern__ extern // CXX2A:#define __private_extern__ extern
// //
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++17 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Z %s
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++1z -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Z %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++1z -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Z %s
// //
// CXX1Z:#define __GNUG__ 4 // CXX1Z:#define __GNUG__ 4
@ -28,6 +30,7 @@
// CXX1Z:#define __private_extern__ extern // CXX1Z:#define __private_extern__ extern
// //
// //
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++14 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Y %s
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++1y -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Y %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++1y -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Y %s
// //
// CXX1Y:#define __GNUG__ 4 // CXX1Y:#define __GNUG__ 4
@ -119,14 +122,16 @@
// RUN: %clang_cc1 -ffreestanding -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix FREESTANDING %s // RUN: %clang_cc1 -ffreestanding -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix FREESTANDING %s
// FREESTANDING:#define __STDC_HOSTED__ 0 // FREESTANDING:#define __STDC_HOSTED__ 0
// //
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++20 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2A %s
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2A %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2A %s
// //
// GXX2A:#define __GNUG__ 4 // GXX2A:#define __GNUG__ 4
// GXX2A:#define __GXX_WEAK__ 1 // GXX2A:#define __GXX_WEAK__ 1
// GXX2A:#define __cplusplus 201707L // GXX2A:#define __cplusplus 202002L
// GXX2A:#define __private_extern__ extern // GXX2A:#define __private_extern__ extern
// //
// //
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++17 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Z %s
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++1z -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Z %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++1z -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Z %s
// //
// GXX1Z:#define __GNUG__ 4 // GXX1Z:#define __GNUG__ 4
@ -135,6 +140,7 @@
// GXX1Z:#define __private_extern__ extern // GXX1Z:#define __private_extern__ extern
// //
// //
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++14 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Y %s
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++1y -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Y %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++1y -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Y %s
// //
// GXX1Y:#define __GNUG__ 4 // GXX1Y:#define __GNUG__ 4

View File

@ -1,30 +1,30 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++17 -pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++2a -Wc++17-compat-pedantic -verify %s -Wno-defaulted-function-deleted // RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wc++17-compat-pedantic -verify %s -Wno-defaulted-function-deleted
struct A {}; struct A {};
int (A::*pa)() const&; int (A::*pa)() const&;
int use_pa = (A().*pa)(); int use_pa = (A().*pa)();
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension}} // expected-warning@-2 {{invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension}}
#else #else
// expected-warning@-4 {{invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++20}}
#endif #endif
struct B { struct B {
void b() { void b() {
(void) [=, this] {}; (void) [=, this] {};
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{explicit capture of 'this' with a capture default of '=' is a C++2a extension}} // expected-warning@-2 {{explicit capture of 'this' with a capture default of '=' is a C++20 extension}}
#else #else
// expected-warning@-4 {{explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++20}}
#endif #endif
} }
int n : 5 = 0; int n : 5 = 0;
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{default member initializer for bit-field is a C++2a extension}} // expected-warning@-2 {{default member initializer for bit-field is a C++20 extension}}
#else #else
// expected-warning@-4 {{default member initializer for bit-field is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{default member initializer for bit-field is incompatible with C++ standards before C++20}}
#endif #endif
}; };
@ -33,14 +33,14 @@ decltype(Lambda) AnotherLambda;
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{no matching constructor}} expected-note@-3 2{{candidate}} // expected-error@-2 {{no matching constructor}} expected-note@-3 2{{candidate}}
#else #else
// expected-warning@-4 {{default construction of lambda is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{default construction of lambda is incompatible with C++ standards before C++20}}
#endif #endif
void copy_lambda() { Lambda = Lambda; } void copy_lambda() { Lambda = Lambda; }
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{deleted}} expected-note@-10 {{lambda}} // expected-error@-2 {{deleted}} expected-note@-10 {{lambda}}
#else #else
// expected-warning@-4 {{assignment of lambda is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{assignment of lambda is incompatible with C++ standards before C++20}}
#endif #endif
struct DefaultDeleteWrongTypeBase { struct DefaultDeleteWrongTypeBase {
@ -51,16 +51,16 @@ struct DefaultDeleteWrongType : DefaultDeleteWrongTypeBase {
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{a member or base requires it to be non-const}} // expected-error@-2 {{a member or base requires it to be non-const}}
#else #else
// expected-warning@-4 {{explicitly defaulting this copy constructor with a type different from the implicit type is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{explicitly defaulting this copy constructor with a type different from the implicit type is incompatible with C++ standards before C++20}}
#endif #endif
}; };
void ForRangeInit() { void ForRangeInit() {
for (int arr[3] = {1, 2, 3}; int n : arr) {} for (int arr[3] = {1, 2, 3}; int n : arr) {}
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{range-based for loop initialization statements are a C++2a extension}} // expected-warning@-2 {{range-based for loop initialization statements are a C++20 extension}}
#else #else
// expected-warning@-4 {{range-based for loop initialization statements are incompatible with C++ standards before C++2a}} // expected-warning@-4 {{range-based for loop initialization statements are incompatible with C++ standards before C++20}}
#endif #endif
} }
@ -69,23 +69,23 @@ struct ConstexprVirtual {
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{virtual function cannot be constexpr}} // expected-error@-2 {{virtual function cannot be constexpr}}
#else #else
// expected-warning@-4 {{virtual constexpr functions are incompatible with C++ standards before C++2a}} // expected-warning@-4 {{virtual constexpr functions are incompatible with C++ standards before C++20}}
#endif #endif
}; };
struct C { int x, y, z; }; struct C { int x, y, z; };
static auto [cx, cy, cz] = C(); static auto [cx, cy, cz] = C();
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{decomposition declaration declared 'static' is a C++2a extension}} // expected-warning@-2 {{decomposition declaration declared 'static' is a C++20 extension}}
#else #else
// expected-warning@-4 {{decomposition declaration declared 'static' is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{decomposition declaration declared 'static' is incompatible with C++ standards before C++20}}
#endif #endif
void f() { void f() {
static thread_local auto [cx, cy, cz] = C(); static thread_local auto [cx, cy, cz] = C();
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{decomposition declaration declared with 'static thread_local' specifiers is a C++2a extension}} // expected-warning@-2 {{decomposition declaration declared with 'static thread_local' specifiers is a C++20 extension}}
#else #else
// expected-warning@-4 {{decomposition declaration declared with 'static thread_local' specifiers is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{decomposition declaration declared with 'static thread_local' specifiers is incompatible with C++ standards before C++20}}
#endif #endif
} }
@ -103,7 +103,7 @@ struct DefaultedComparisons {
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-error@-2 {{'operator<=' cannot be the name of a variable or data member}} expected-error@-2 0+{{}} expected-warning@-2 {{}} // expected-error@-2 {{'operator<=' cannot be the name of a variable or data member}} expected-error@-2 0+{{}} expected-warning@-2 {{}}
#else #else
// expected-warning@-4 {{'<=>' operator is incompatible with C++ standards before C++2a}} // expected-warning@-4 {{'<=>' operator is incompatible with C++ standards before C++20}}
#endif #endif
bool operator<(const DefaultedComparisons&) const = default; bool operator<(const DefaultedComparisons&) const = default;
bool operator<=(const DefaultedComparisons&) const = default; bool operator<=(const DefaultedComparisons&) const = default;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions
// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks %s -fcxx-exceptions // RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -fblocks %s -fcxx-exceptions
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions
@ -25,7 +25,7 @@ namespace ns1 {
namespace ns2 { namespace ns2 {
auto L = [](int I) constexpr { if (I == 5) asm("non-constexpr"); }; auto L = [](int I) constexpr { if (I == 5) asm("non-constexpr"); };
#if __cpp_constexpr < 201907L #if __cpp_constexpr < 201907L
//expected-warning@-2{{use of this statement in a constexpr function is a C++2a extension}} //expected-warning@-2{{use of this statement in a constexpr function is a C++20 extension}}
#endif #endif
} // end ns1 } // end ns1

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -std=c++1z -verify %s // RUN: %clang_cc1 -std=c++17 -verify %s
void use_from_own_init() { void use_from_own_init() {
auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}} auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
@ -83,7 +83,7 @@ template <class T> void dependent_foreach(T t) {
struct PR37352 { struct PR37352 {
int n; int n;
void f() { static auto [a] = *this; } // expected-warning {{C++2a extension}} void f() { static auto [a] = *this; } // expected-warning {{C++20 extension}}
}; };
namespace instantiate_template { namespace instantiate_template {

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++2a-compat-pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++20-compat-pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++2a -pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++20 -pedantic -verify %s
struct A { // expected-note 0+{{candidate}} struct A { // expected-note 0+{{candidate}}
A() = default; // expected-note 0+{{candidate}} A() = default; // expected-note 0+{{candidate}}
@ -7,7 +7,7 @@ struct A { // expected-note 0+{{candidate}}
}; };
A a1 = {1, 2}; A a1 = {1, 2};
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 {{aggregate initialization of type 'A' with user-declared constructors is incompatible with C++2a}} // expected-warning@-2 {{aggregate initialization of type 'A' with user-declared constructors is incompatible with C++20}}
#else #else
// expected-error@-4 {{no matching constructor}} // expected-error@-4 {{no matching constructor}}
#endif #endif
@ -17,7 +17,7 @@ struct B : A { A a; };
B b1 = {{}, {}}; // ok B b1 = {{}, {}}; // ok
B b2 = {1, 2, 3, 4}; B b2 = {1, 2, 3, 4};
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-2 2{{aggregate initialization of type 'A' with user-declared constructors is incompatible with C++2a}} // expected-warning@-2 2{{aggregate initialization of type 'A' with user-declared constructors is incompatible with C++20}}
#else #else
// expected-error@-4 2{{no viable conversion from 'int' to 'A'}} // expected-error@-4 2{{no viable conversion from 'int' to 'A'}}
#endif #endif
@ -43,7 +43,7 @@ struct C {
explicit(C)(int); explicit(C)(int);
}; };
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-3 {{this expression will be parsed as explicit(bool) in C++2a}} // expected-warning@-3 {{this expression will be parsed as explicit(bool) in C++20}}
#if defined(__cpp_conditional_explicit) #if defined(__cpp_conditional_explicit)
#error "the feature test macro __cpp_conditional_explicit isn't correct" #error "the feature test macro __cpp_conditional_explicit isn't correct"
#endif #endif
@ -61,8 +61,8 @@ struct C {
auto l = []() consteval {}; auto l = []() consteval {};
int consteval(); int consteval();
#if __cplusplus <= 201703L #if __cplusplus <= 201703L
// expected-warning@-3 {{'consteval' is a keyword in C++2a}} // expected-warning@-3 {{'consteval' is a keyword in C++20}}
// expected-error@-4 {{expected body of lambda expression}} // expected-error@-4 {{expected body of lambda expression}}
#else #else
// expected-error@-5 {{expected unqualified-id}} // expected-error@-5 {{expected unqualified-id}}
#endif #endif

View File

@ -1,9 +1,9 @@
// RUN: %clang_cc1 -std=c++2a %s -verify=cxx20,expected,pedantic,override,reorder -pedantic-errors // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,pedantic,override,reorder -pedantic-errors
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,pedantic,override,reorder -Wno-c++2a-designator -pedantic-errors // RUN: %clang_cc1 -std=c++17 %s -verify=expected,pedantic,override,reorder -Wno-c++20-designator -pedantic-errors
// RUN: %clang_cc1 -std=c++2a %s -verify=cxx20,expected,pedantic -Werror=c99-designator -Wno-reorder-init-list -Wno-initializer-overrides // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,pedantic -Werror=c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
// RUN: %clang_cc1 -std=c++2a %s -verify=cxx20,expected,reorder -Wno-c99-designator -Werror=reorder-init-list -Wno-initializer-overrides // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,reorder -Wno-c99-designator -Werror=reorder-init-list -Wno-initializer-overrides
// RUN: %clang_cc1 -std=c++2a %s -verify=cxx20,expected,override -Wno-c99-designator -Wno-reorder-init-list -Werror=initializer-overrides // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,override -Wno-c99-designator -Wno-reorder-init-list -Werror=initializer-overrides
// RUN: %clang_cc1 -std=c++2a %s -verify=cxx20,expected -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
namespace class_with_ctor { namespace class_with_ctor {

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s // RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
struct Bitfield { struct Bitfield {
int n : 3 = 7; // expected-warning {{C++2a extension}} expected-warning {{changes value from 7 to -1}} int n : 3 = 7; // expected-warning {{C++20 extension}} expected-warning {{changes value from 7 to -1}}
}; };
int a; int a;

View File

@ -819,14 +819,13 @@ code. This issue is expected to be rectified soon.
</p> </p>
</details> </details>
<h2 id="cxx20">C++2a implementation status</h2> <h2 id="cxx20">C++20 implementation status</h2>
<p>Clang has <b>experimental</b> support for some proposed features of <p>Clang has support for some of the features of the
the C++ standard following C++17, provisionally named C++2a. ISO C++ 2020 Draft International Standard.
Note that support for these features may change or be removed without notice,
as the draft C++2a standard evolves.
<p>You can use Clang in C++2a mode with the <code>-std=c++2a</code> option.</p> <p>You can use Clang in C++20 mode with the <code>-std=c++20</code> option
(use <code>-std=c++2a</code> in Clang 10 and earlier).</p>
<details open> <details open>
<summary>List of features and minimum Clang version with support</summary> <summary>List of features and minimum Clang version with support</summary>
@ -834,7 +833,7 @@ as the draft C++2a standard evolves.
<table width="689" border="1" cellspacing="0"> <table width="689" border="1" cellspacing="0">
<tr> <tr>
<th>Language Feature</th> <th>Language Feature</th>
<th>C++2a Proposal</th> <th>C++20 Proposal</th>
<th>Available in Clang?</th> <th>Available in Clang?</th>
</tr> </tr>
<!-- Toronto 2017 papers --> <!-- Toronto 2017 papers -->
@ -1206,7 +1205,7 @@ as the draft C++2a standard evolves.
<p> <p>
<span id="p0482">(11): Prior to Clang 8, this feature is not enabled by <span id="p0482">(11): Prior to Clang 8, this feature is not enabled by
<tt>-std=c++2a</tt>, but can be enabled with <tt>-fchar8_t</tt>. <tt>-std=c++20</tt>, but can be enabled with <tt>-fchar8_t</tt>.
</span> </span>
</p> </p>
</details> </details>
@ -1299,7 +1298,7 @@ and library features that are not part of standard C++.</p>
<td class="full" align="center">Clang 5</td> <td class="full" align="center">Clang 5</td>
</tr> </tr>
<tr> <tr>
<td><tt>-std=c++2a<br>-stdlib=libc++</tt></td> <td><tt>-std=c++20<br>-stdlib=libc++</tt></td>
<td class="na" align="center">Superseded by <a href="#p0912">P0912R5</a></td> <td class="na" align="center">Superseded by <a href="#p0912">P0912R5</a></td>
</tr> </tr>
<tr> <tr>