constraint expressions.
We create overloaded `&&` and `||` operators to hold the possible
unqualified lookup results (if any) when the operands are dependent. We
could avoid building these in some cases (we will never use the stored
lookup results, and it would be better to not store them or perform the
lookups), but in the general case we will probably still need to handle
overloaded operators even with that optimization.
We should check non-dependent element types before creating a
DependentSizedMatrixType. Otherwise we do not generate an error message
for dependent-sized matrix types with invalid non-dependent element
types, if the template is never instantiated. See the make5 struct in
the tests.
It also moves the SEMA template tests to
clang/test/SemaTemplate/matrix-type.cpp and introduces a few more test
cases.
The 'class' or 'struct' keyword is only permitted as part of either an
enum definition or a standalone opaque-enum-declaration, not as part of
an elaborated type specifier. We previously failed to diagnose this, and
generally didn't properly implement the restrictions on elaborated type
specifiers for enumeration types.
In passing, also fixed incorrect parsing for enum-bases, which we
previously parsed as a type-name, but are actually a type-specifier-seq.
This matters for cases like 'enum E : int *p;', which is valid as a
Microsoft extension.
Plus some minor parse diagnostic improvements.
Bumped the recently-added ExtWarn for 'enum E : int x;' to be
DefaultError; this is not an intentional extension, so producing an
error by default seems appropriate, but the warning flag to disable it
may still be useful for code written against old Clang. The same
treatment is given here to the diagnostic for 'enum class E x;', which
we similarly have incorrectly accepted for many years. These diagnostics
continue to be suppressed under -fms-extensions and when compiling
Objective-C code. We will need to decide separately whether Objective-C
should follow the C++ rules or the (older) MSVC rules.
Summary:
We extend the behavior for local functions and methods of local classes
to lambdas in variable initializers. The initializer is not a separate
scope, but we treat it as such.
We also remove the (faulty) instantiation of default arguments in
TreeTransform::TransformLambdaExpr, because it doesn't do proper
initialization, and if it did, we would do it twice (and thus also emit
eventual errors twice).
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D76038
constructor with default arguments.
We used to try to rebuild the call as a call to the faked-up inherited
constructor, which is only a placeholder and lacks (for example) default
arguments. Instead, build the call by reference to the original
constructor.
In passing, add a note to say where a call that recursively uses a
default argument from within itself occurs. This is usually pretty
obvious, but still at least somewhat useful, and would have saved
significant debugging time for this particular bug.
scope.
There are a few contexts in which we assume a name is a template name;
if such a context is one where we should perform an unqualified lookup,
and lookup finds nothing, we would form a dependent template name even
if the name is not dependent. This happens in particular for the lookup
of a pseudo-destructor.
In passing, rename ActOnDependentTemplateName to just ActOnTemplateName
given that we apply it for non-dependent template names too.
Instead of bailing out of parsing when we encounter an invalid
template-name or template arguments in a template-id, produce an
annotation token describing the invalid construct.
This avoids duplicate errors and generally allows us to recover better.
In principle we should be able to extend this to store some kinds of
invalid template-id in the AST for tooling use, but that isn't handled
as part of this change.
This reverts commit 0788acbccb.
This reverts commit c2d7a1f79cedfc9fcb518596aa839da4de0adb69: Revert "[clangd] Add test for FindTarget+RecoveryExpr (which already works). NFC"
It causes a crash on invalid code:
class X {
decltype(unresolved()) foo;
};
constexpr int s = sizeof(X);
Normally clang avoids creating expressions when it encounters semantic
errors, even if the parser knows which expression to produce.
This works well for the compiler. However, this is not ideal for
source-level tools that have to deal with broken code, e.g. clangd is
not able to provide navigation features even for names that compiler
knows how to resolve.
The new RecoveryExpr aims to capture the minimal set of information
useful for the tools that need to deal with incorrect code:
source range of the expression being dropped,
subexpressions of the expression.
We aim to make constructing RecoveryExprs as simple as possible to
ensure writing code to avoid dropping expressions is easy.
Producing RecoveryExprs can result in new code paths being taken in the
frontend. In particular, clang can produce some new diagnostics now and
we aim to suppress bogus ones based on Expr::containsErrors.
We deliberately produce RecoveryExprs only in the parser for now to
minimize the code affected by this patch. Producing RecoveryExprs in
Sema potentially allows to preserve more information (e.g. type of an
expression), but also results in more code being affected. E.g.
SFINAE checks will have to take presence of RecoveryExprs into account.
Initial implementation only works in C++ mode, as it relies on compiler
postponing diagnostics on dependent expressions. C and ObjC often do not
do this, so they require more work to make sure we do not produce too
many bogus diagnostics on the new expressions.
See documentation of RecoveryExpr for more details.
original patch from Ilya
This change is based on https://reviews.llvm.org/D61722
Reviewers: sammccall, rsmith
Reviewed By: sammccall, rsmith
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69330
Suppress those diagnostics if lhs of a member expression contains
errors. Typo correction produces dependent expressions even in
non-template code, that led to spurious diagnostics before.
previous:
/tmp/t.cpp:6:17: error: use 'template' keyword to treat 'f' as a dependent template name
auto a = bilder.f<int>();
^
template
/tmp/t.cpp:6:10: error: use of undeclared identifier 'bilder'; did you mean 'builder'?
auto a = bilder.f<int>();
^~~~~~
builder
vs now:
/tmp/t.cpp:6:10: error: use of undeclared identifier 'bilder'; did you mean 'builder'?
auto a = bilder.f<int>();
^~~~~~
builder
Original patch from Ilya.
Reviewers: sammccall
Reviewed By: sammccall
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65592
TryAnnotateTypeConstraint could annotate a template-id which doesn't end up being a type-constraint,
in which case control flow would incorrectly flow into ParseImplicitInt.
Reenter the loop in this case.
Enable relevant tests for C++20. This required disabling typo-correction during TryAnnotateTypeConstraint
and changing a test case which is broken due to a separate bug (will be reported and handled separately).
a dependent context.
This matches the GCC behavior.
We track the enclosing template depth when determining whether a
statement expression is within a dependent context; there doesn't appear
to be any other reliable way to determine this.
We previously assumed they were neither value- nor
instantiation-dependent under any circumstances, which would lead to
crashes and other misbehavior.
We would assign the incorrect DeclContext when transforming the RequiresExprBodyDecl, causing incorrect
handling of 'this' inside RequiresExprBodyDecls (bug #45162).
Assign the current context as the DeclContext of the transformed decl.
dependent constructs.
We previously assumed they were neither value- nor
instantiation-dependent under any circumstances, which would lead to
crashes and other misbehavior.
This doesn't match GCC's behavior (where statement expressions appear to
be treated as value-dependent if they appear in a dependent context),
but seems to be the best thing we can do in the short term: it turns out
to be remarkably difficult for us to correctly determine whether we are
in a dependent context (and it's not even possible in some cases, such
as in a generic lambda where we might not have seen the 'auto' yet).
This was previously reverted in 8e4a867 for rejecting some code, but that
code was invalid and Clang was previously incorrectly accepting it.
GetContainedInventedTypeParmVisitor would not account for the case where TemplateTypeParmType::getDecl() is
nullptr, causing bug #45102.
Add the nullptr check.
dependent constructs.
We previously assumed they were neither value- nor
instantiation-dependent under any circumstances, which would lead to
crashes and other misbehavior.
This doesn't match GCC's behavior (where statement expressions appear to
be treated as value-dependent if they appear in a dependent context),
but seems to be the best thing we can do in the short term: it turns out
to be remarkably difficult for us to correctly determine whether we are
in a dependent context (and it's not even possible in some cases, such
as in a generic lambda where we might not have seen the 'auto' yet).
dependent contexts.
We previously assumed they were neither value- nor
instantiation-dependent under any circumstances, which would lead to
crashes and other misbehavior.
Compute and propagate conversion kind to diagnostics helper in C++
to provide more specific diagnostics about incorrect implicit
conversions in assignments, initializations, params, etc...
Duplicated some diagnostics as errors because C++ is more strict.
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74116
This patch is a follow up to 878a24ee24. Name of bitfields
with value-dependent width should be set as type-dependent. This
patch adds the required value-dependency check and sets the
type-dependency accordingly.
Patch fixes PR44886
Differential revision: https://reviews.llvm.org/D72242
Summary:
Due to a recent (but retroactive) C++ rule change, only sufficiently
C-compatible classes are permitted to be given a typedef name for
linkage purposes. Add an enabled-by-default warning for these cases, and
rephrase our existing error for the case where we encounter the typedef
name for linkage after we've already computed and used a wrong linkage
in terms of the new rule.
Reviewers: rjmccall
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74103
constant initialization.
Removing this zeroing regressed our code generation in a few cases, also
fixed here. We now compute whether a variable has constant destruction
even if it doesn't have a constant initializer, by trying to destroy a
default-initialized value, and skip emitting a trivial default
constructor for a variable even if it has non-trivial (but perhaps
constant) destruction.
We would incorrectly check whether the type-constraint had already been initialized, causing us
to ignore the invented template type constraints entirely.
Also, TemplateParameterList would store incorrect information about invented type parameters
when it observed them before their type-constraint was initialized, so we recreate it after
initializing the function type of an abbreviated template.
We did not have a CXXThisScope around constraint checking of functions and
function template specializations, causing a crash when checking a constraint
that had a 'this' (bug 44689).
Recommit after fixing test.
We did not have a CXXThisScope around constraint checking of functions and
function template specializations, causing a crash when checking a constraint
that had a 'this' (bug 44689)
We previously instantiated type-constraints of template type parameters along with the type parameter itself,
this caused problems when the type-constraints created by abbreviated templates refreneced other parameters
in the abbreviated templates.
When encountering a template type parameter with a type constraint, if it is implicit, delay instantiation of
the type-constraint until the function parameter which created the invented template type parameter is
instantiated.
Reland after fixing bug caused by another flow reaching SubstParmVarDecl and instantiating the TypeConstraint
a second time.
We previously instantiated type-constraints of template type parameters along with the type parameter itself,
this caused problems when the type-constraints created by abbreviated templates refreneced other parameters
in the abbreviated templates.
When encountering a template type parameter with a type constraint, if it is implicit, delay instantiation of
the type-constraint until the function parameter which created the invented template type parameter is
instantiated.
We previously would not correctly for the initial parameter mapping for variadic template parameters in Concepts.
Testing this lead to the discovery that with the normalization process we would need to substitute into already-substituted-into
template arguments, which means we need to add NonTypeTemplateParmExpr support to TemplateInstantiator.
We do that by substituting into the replacement and the type separately, and then re-checking the expression against the NTTP
with the new type, in order to form any new required implicit casts (for cases where the type of the NTTP was dependent).
We would previously try to evaluate atomic constraints of non-template functions as-is,
and since they are now unevaluated at first, this would cause incorrect evaluation (bugs #44657, #44656).
Substitute into atomic constraints of non-template functions as we would atomic constraints
of template functions, in order to rebuild the expressions in a constant-evaluated context.
As per P1980R0, constraint expressions are unevaluated operands, and their constituent atomic
constraints only become constant evaluated during satisfaction checking.
Change the evaluation context during parsing and instantiation of constraints to unevaluated.
Now with concepts support merged and mostly complete, we do not need -fconcepts-ts
(which was also misleading as we were not implementing the TS) and can enable
concepts features under C++2a. A warning will be generated if users still attempt
to use -fconcepts-ts.
Proper ExpressionEvaluationContext were not being entered when instantiating constraint
expressions, which caused assertion failures in certain cases, including bug #44614.
This patch implements P1141R2 "Yet another approach for constrained declarations".
General strategy for this patch was:
- Expand AutoType to include optional type-constraint, reflecting the wording and easing the integration of constraints.
- Replace autos in parameter type specifiers with invented parameters in GetTypeSpecTypeForDeclarator, using the same logic
previously used for generic lambdas, now unified with abbreviated templates, by:
- Tracking the template parameter lists in the Declarator object
- Tracking the template parameter depth before parsing function declarators (at which point we can match template
parameters against scope specifiers to know if we have an explicit template parameter list to append invented parameters
to or not).
- When encountering an AutoType in a parameter context we check a stack of InventedTemplateParameterInfo structures that
contain the info required to create and accumulate invented template parameters (fields that were already present in
LambdaScopeInfo, which now inherits from this class and is looked up when an auto is encountered in a lambda context).
Resubmit after fixing MSAN failures caused by incomplete initialization of AutoTypeLocs in TypeSpecLocFiller.
Differential Revision: https://reviews.llvm.org/D65042