summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-09-18 17:37:44 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-09-18 17:37:44 +0000
commit5e9c2181fcc9614b760e7ce1eceddd06d611b48d (patch)
tree1d5b61b296969fc9571ac3f0ead4c1fdc4e10f67 /include
parentb54c5533a96089475662f89385f24b48a902b585 (diff)
downloadclang-5e9c2181fcc9614b760e7ce1eceddd06d611b48d.tar.gz
[c++20] P1331R2: Allow transient use of uninitialized objects in
constant evaluation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372237 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/DeclCXX.h3
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td44
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td30
3 files changed, 48 insertions, 29 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index f9668f1dce..49a0e6e982 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1352,7 +1352,8 @@ public:
/// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
- (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
+ (!isUnion() || hasInClassInitializer() || !hasVariantMembers() ||
+ getASTContext().getLangOpts().CPlusPlus2a);
}
/// Determine whether this class has a constexpr default constructor.
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 7732be5659..98c1269e03 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -37,7 +37,7 @@ def note_constexpr_virtual_call : Note<
def note_constexpr_pure_virtual_call : Note<
"pure virtual function %q0 called">;
def note_constexpr_polymorphic_unknown_dynamic_type : Note<
- "%select{||||virtual function called on|dynamic_cast applied to|"
+ "%select{|||||virtual function called on|dynamic_cast applied to|"
"typeid applied to}0 object '%1' whose dynamic type is not constant">;
def note_constexpr_dynamic_cast_to_reference_failed : Note<
"reference dynamic_cast failed: %select{"
@@ -113,12 +113,12 @@ def note_constexpr_this : Note<
"%select{|implicit }0use of 'this' pointer is only allowed within the "
"evaluation of a call to a 'constexpr' member function">;
def note_constexpr_lifetime_ended : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 "
"%select{temporary|variable}1 whose lifetime has ended">;
def note_constexpr_access_uninit : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 "
"%select{object outside its lifetime|uninitialized object}1 "
"is not allowed in a constant expression">;
def note_constexpr_use_uninit_reference : Note<
@@ -128,10 +128,12 @@ def note_constexpr_modify_const_type : Note<
"modification of object of const-qualified type %0 is not allowed "
"in a constant expression">;
def note_constexpr_access_volatile_type : Note<
- "%select{read of|assignment to|increment of|decrement of|<ERROR>|<ERROR>}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "<ERROR>|<ERROR>}0 "
"volatile-qualified type %1 is not allowed in a constant expression">;
def note_constexpr_access_volatile_obj : Note<
- "%select{read of|assignment to|increment of|decrement of|<ERROR>|<ERROR>}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "<ERROR>|<ERROR>}0 "
"volatile %select{temporary|object %2|member %2}1 is not allowed in "
"a constant expression">;
def note_constexpr_volatile_here : Note<
@@ -145,31 +147,33 @@ def note_constexpr_ltor_non_constexpr : Note<
def note_constexpr_ltor_incomplete_type : Note<
"read of incomplete type %0 is not allowed in a constant expression">;
def note_constexpr_access_null : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 "
"dereferenced null pointer is not allowed in a constant expression">;
def note_constexpr_access_past_end : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
- "dereferenced one-past-the-end pointer is not allowed in a constant expression">;
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 "
+ "dereferenced one-past-the-end pointer is not allowed "
+ "in a constant expression">;
def note_constexpr_access_unsized_array : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 "
"element of array without known bound "
"is not allowed in a constant expression">;
def note_constexpr_access_inactive_union_member : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 "
"member %1 of union with %select{active member %3|no active member}2 "
"is not allowed in a constant expression">;
def note_constexpr_access_static_temporary : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 temporary "
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 temporary "
"is not allowed in a constant expression outside the expression that "
"created the temporary">;
def note_constexpr_access_unreadable_object : Note<
- "%select{read of|assignment to|increment of|decrement of|member call on|"
- "dynamic_cast of|typeid applied to}0 object '%1' whose value is not known">;
+ "%select{read of|read of|assignment to|increment of|decrement of|"
+ "member call on|dynamic_cast of|typeid applied to}0 object '%1' "
+ "whose value is not known">;
def note_constexpr_modify_global : Note<
"a constant expression cannot modify an object that is visible outside "
"that expression">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 35cca1303b..b89bd36757 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2438,9 +2438,13 @@ def err_constexpr_local_var_static : Error<
def err_constexpr_local_var_non_literal_type : Error<
"variable of non-literal type %1 cannot be defined in a constexpr "
"%select{function|constructor}0">;
-def err_constexpr_local_var_no_init : Error<
- "variables defined in a constexpr %select{function|constructor}0 must be "
- "initialized">;
+def ext_constexpr_local_var_no_init : ExtWarn<
+ "uninitialized variable in a constexpr %select{function|constructor}0 "
+ "is a C++20 extension">, InGroup<CXX2a>;
+def warn_cxx17_compat_constexpr_local_var_no_init : Warning<
+ "uninitialized variable in a constexpr %select{function|constructor}0 "
+ "is incompatible with C++ standards before C++20">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
def ext_constexpr_function_never_constant_expr : ExtWarn<
"constexpr %select{function|constructor}0 never produces a "
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
@@ -2468,7 +2472,7 @@ def note_constexpr_body_previous_return : Note<
def err_constexpr_function_try_block : Error<
"function try block not allowed in constexpr %select{function|constructor}0">;
-// c++2a function try blocks in constexpr
+// C++2a function try blocks in constexpr
def ext_constexpr_function_try_block_cxx2a : ExtWarn<
"function try block in constexpr %select{function|constructor}0 is "
"a C++2a extension">, InGroup<CXX2a>;
@@ -2477,10 +2481,20 @@ def warn_cxx17_compat_constexpr_function_try_block : Warning<
"incompatible with C++ standards before C++2a">,
InGroup<CXXPre2aCompat>, DefaultIgnore;
-def err_constexpr_union_ctor_no_init : Error<
- "constexpr union constructor does not initialize any member">;
-def err_constexpr_ctor_missing_init : Error<
- "constexpr constructor must initialize all members">;
+def ext_constexpr_union_ctor_no_init : ExtWarn<
+ "constexpr union constructor that does not initialize any member "
+ "is a C++20 extension">, InGroup<CXX2a>;
+def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning<
+ "constexpr union constructor that does not initialize any member "
+ "is incompatible with C++ standards before C++20">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
+def ext_constexpr_ctor_missing_init : ExtWarn<
+ "constexpr constructor that does not initialize all members "
+ "is a C++20 extension">, InGroup<CXX2a>;
+def warn_cxx17_compat_constexpr_ctor_missing_init : Warning<
+ "constexpr constructor that does not initialize all members "
+ "is incompatible with C++ standards before C++20">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
def note_constexpr_ctor_missing_init : Note<
"member not initialized by constructor">;
def note_non_literal_no_constexpr_ctors : Note<