We were already performing checks on non-template variables,
but the checks on templated ones were missing.
Differential Revision: https://reviews.llvm.org/D45231
llvm-svn: 329127
The AST for the fragment
```
@interface I
@end
template <typename>
void decode(I *p) {
for (I *k in p) {}
}
void decode(I *p) {
decode<int>(p);
}
```
differs heavily when templatized and non-templatized:
```
|-FunctionTemplateDecl 0x7fbfe0863940 <line:4:1, line:7:1> line:5:6 decode
| |-TemplateTypeParmDecl 0x7fbfe0863690 <line:4:11> col:11 typename depth 0 index 0
| |-FunctionDecl 0x7fbfe08638a0 <line:5:1, line:7:1> line:5:6 decode 'void (I *__strong)'
| | |-ParmVarDecl 0x7fbfe08637a0 <col:13, col:16> col:16 referenced p 'I *__strong'
| | `-CompoundStmt 0x7fbfe0863b88 <col:19, line:7:1>
| | `-ObjCForCollectionStmt 0x7fbfe0863b50 <line:6:3, col:20>
| | |-DeclStmt 0x7fbfe0863a50 <col:8, col:13>
| | | `-VarDecl 0x7fbfe08639f0 <col:8, col:11> col:11 k 'I *const __strong'
| | |-ImplicitCastExpr 0x7fbfe0863a90 <col:16> 'I *' <LValueToRValue>
| | | `-DeclRefExpr 0x7fbfe0863a68 <col:16> 'I *__strong' lvalue ParmVar 0x7fbfe08637a0 'p' 'I *__strong'
| | `-CompoundStmt 0x7fbfe0863b78 <col:19, col:20>
| `-FunctionDecl 0x7fbfe0863f80 <line:5:1, line:7:1> line:5:6 used decode 'void (I *__strong)'
| |-TemplateArgument type 'int'
| |-ParmVarDecl 0x7fbfe0863ef8 <col:13, col:16> col:16 used p 'I *__strong'
| `-CompoundStmt 0x7fbfe0890cf0 <col:19, line:7:1>
| `-ObjCForCollectionStmt 0x7fbfe0890cc8 <line:6:3, col:20>
| |-DeclStmt 0x7fbfe0890c70 <col:8, col:13>
| | `-VarDecl 0x7fbfe0890c00 <col:8, col:11> col:11 k 'I *__strong' callinit
| | `-ImplicitValueInitExpr 0x7fbfe0890c60 <<invalid sloc>> 'I *__strong'
| |-ImplicitCastExpr 0x7fbfe0890cb0 <col:16> 'I *' <LValueToRValue>
| | `-DeclRefExpr 0x7fbfe0890c88 <col:16> 'I *__strong' lvalue ParmVar 0x7fbfe0863ef8 'p' 'I *__strong'
| `-CompoundStmt 0x7fbfe0863b78 <col:19, col:20>
```
Note how in the instantiated version ImplicitValueInitExpr unexpectedly appears.
While objects are auto-initialized under ARC, it does not make sense to
have an initializer for a for-loop variable, and it makes even less
sense to have such a different AST for instantiated and non-instantiated
version.
Digging deeper, I have found that there are two separate Sema* files for
dealing with templates and for dealing with non-templatized code.
In a non-templatized version, an initialization was performed only for
variables which are not loop variables for an Objective-C loop and not
variables for a C++ for-in loop:
```
if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
bool IsForRangeLoop = false;
if (TryConsumeToken(tok::colon, FRI->ColonLoc)) {
IsForRangeLoop = true;
if (Tok.is(tok::l_brace))
FRI->RangeExpr = ParseBraceInitializer();
else
FRI->RangeExpr = ParseExpression();
}
Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
if (IsForRangeLoop)
Actions.ActOnCXXForRangeDecl(ThisDecl);
Actions.FinalizeDeclaration(ThisDecl);
D.complete(ThisDecl);
return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);
}
SmallVector<Decl *, 8> DeclsInGroup;
Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(
D, ParsedTemplateInfo(), FRI);
```
However the code in SemaTemplateInstantiateDecl was inconsistent,
guarding only against C++ for-in loops.
rdar://38391075
Differential Revision: https://reviews.llvm.org/D44989
llvm-svn: 328749
Summary:
This fixes PR33561 and PR34185.
Don't store pending template instantiations for late-parsed templates in
the normal PendingInstantiations queue. Instead, use a separate list
that will only be parsed and instantiated at end of TU when late
template parsing actually works and doesn't infinite loop.
Reviewers: rsmith, thakis, hans
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D44846
llvm-svn: 328567
Digging through commit logs, it appears the checks in this block predate
`inline` class variables. With them, we fail to emit dynamic
initializers for members that don't have an explicit initializer, and we
won't go out of our way to instantiate the class denoted by
`Var->getType()`.
Fixes PR35599.
llvm-svn: 327945
More generally, this permits a template to be specialized in any scope in which
it could be defined, so this also supersedes DR44 and DR374 (the latter of
which we previously only implemented in C++11 mode onwards due to unclarity as
to whether it was a DR).
llvm-svn: 327705
Use an enum parameter instead of a bool for more control on how the copy elision
functions work. Extract the move initialization code from the move or copy
initialization block.
Patch by: Arthur O'Dwyer
Differential Revision: https://reviews.llvm.org/D43898
llvm-svn: 327598
Summary:
By calling ActOnFinishFunctionBody(). Previously we were only calling
ActOnSkippedFunctionBody, which didn't pop the function scope.
This causes a crash when running on our internal code. No test-case,
though, since I couldn't come up with a small example in reasonable
time.
The bug was introduced in r321174.
Reviewers: bkramer, sammccall, sepavloff, aaron.ballman
Reviewed By: sammccall, aaron.ballman
Subscribers: aaron.ballman, cfe-commits
Differential Revision: https://reviews.llvm.org/D44439
llvm-svn: 327504
template parameter that is an expanded parameter pack, only substitute into the
current slice, not the entire pack.
This reduces the checking of N template template arguments for an expanded
parameter pack containing N parameters from quadratic time to linear time in
the length of the pack. This is important because one (and possibly the only?)
general technique for splitting a template parameter pack in linear time
depends on doing this.
llvm-svn: 326973
The patch fixes a number of bugs related to parameter indexing in
attributes:
* Parameter indices in some attributes (argument_with_type_tag,
pointer_with_type_tag, nonnull, ownership_takes, ownership_holds,
and ownership_returns) are specified in source as one-origin
including any C++ implicit this parameter, were stored as
zero-origin excluding any this parameter, and were erroneously
printing (-ast-print) and confusingly dumping (-ast-dump) as the
stored values.
* For alloc_size, the C++ implicit this parameter was not subtracted
correctly in Sema, leading to assert failures or to silent failures
of __builtin_object_size to compute a value.
* For argument_with_type_tag, pointer_with_type_tag, and
ownership_returns, the C++ implicit this parameter was not added
back to parameter indices in some diagnostics.
This patch fixes the above bugs and aims to prevent similar bugs in
the future by introducing careful mechanisms for handling parameter
indices in attributes. ParamIdx stores a parameter index and is
designed to hide the stored encoding while providing accessors that
require each use (such as printing) to make explicit the encoding that
is needed. Attribute declarations declare parameter index arguments
as [Variadic]ParamIdxArgument, which are exposed as ParamIdx[*]. This
patch rewrites all attribute arguments that are processed by
checkFunctionOrMethodParameterIndex in SemaDeclAttr.cpp to be declared
as [Variadic]ParamIdxArgument. The only exception is xray_log_args's
argument, which is encoded as a count not an index.
Differential Revision: https://reviews.llvm.org/D43248
llvm-svn: 326602
Current implementation of `FunctionDecl::isDefined` does not take into
account redeclarations that do not have bodies, but the bodies can be
instantiated from corresponding templated definition. This behavior does
not allow to detect function redefinition in the cases where friend
functions is defined in class templates. For instance, the code:
```
template<typename T> struct X { friend void f() {} };
X<int> xi;
void f() {}
```
compiles successfully but must fail due to redefinition of `f`. The
declaration of the friend `f` is created when the containing template
`X` is instantiated, but it does not have a body as per 14.5.4p4
because `f` is not odr-used.
With this change the function `Sema::CheckForFunctionRedefinition`
considers functions with uninstantiated bodies as definitions.
Differential Revision: https://reviews.llvm.org/D30170
llvm-svn: 326419
So I wrote a clang-tidy check to lint out redundant `isa`, `cast`, and
`dyn_cast`s for fun. This is a portion of what it found for clang; I
plan to do similar cleanups in LLVM and other subprojects when I find
time.
Because of the volume of changes, I explicitly avoided making any change
that wasn't highly local and obviously correct to me (e.g. we still have
a number of foo(cast<Bar>(baz)) that I didn't touch, since overloading
is a thing and the cast<Bar> did actually change the type -- just up the
class hierarchy).
I also tried to leave the types we were cast<>ing to somewhere nearby,
in cases where it wasn't locally obvious what we were dealing with
before.
llvm-svn: 326416
Summary:
This fixes a flaw in our AST: PR27098
MSVC always gives plain enums the underlying type 'int'. Clang does this
as well, but we claim the enum is "fixed", as if the user actually wrote
': int'. It means we end up emitting spurious -Wsign-compare warnings on
code like this:
enum Vals { E1, E2, E3 };
bool f(unsigned v1, Vals v2) {
return v1 == v2;
}
We think 'v2' can take on negative values because we think 'Vals' is
fixed. This fixes that.
Reviewers: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D43110
llvm-svn: 324913
This patch adds a base-class called TemplateInstantiationObserver which gets
notified whenever a template instantiation is entered or exited during
semantic analysis. This is a base class used to implement the template
profiling and debugging tool called
Templight (https://github.com/mikael-s-persson/templight).
The patch also makes a few more changes:
* ActiveTemplateInstantiation class is moved out of the Sema class (so it can be used with inclusion of Sema.h).
* CreateFrontendAction function in front-end utilities is given external linkage (not longer a hidden static function).
* TemplateInstObserverChain data member added to Sema class to hold the list of template-inst observers.
* Notifications to the template-inst observer are added at the key places where templates are instantiated.
Patch by: Abel Sinkovics!
Differential Revision: https://reviews.llvm.org/D5767
llvm-svn: 324808
each kind.
Attribute instantiation would previously default to instantiating each kind of
attribute only once. This was overridden by a flag whose intended purpose was
to permit attributes from a prior declaration to be inherited onto a new
declaration even if that new declaration had its own copy of the attribute.
This is the wrong behavior: when instantiating attributes from a template, we
should always instantiate all the attributes that were written on that
template.
This patch renames the flag in the Attr class (and TableGen sources) to more
clearly identify what it's actually for, and removes the usage of the flag from
template instantiation. I also removed the flag from AlignedAttr, which was
only added to work around the incorrect suppression of duplicate attribute
instantiation.
llvm-svn: 321834
Previously, we would:
* compute the type of the conversion function and static invoker as a
side-effect of template argument deduction for a conversion
* re-compute the type as part of deduced return type deduction when building
the conversion function itself
Neither of these turns out to be quite correct. There are other ways to reach a
declaration of the conversion function than in a conversion (such as an
explicit call or friend declaration), and performing auto deduction causes the
function type to be rebuilt in the context of the lambda closure type (which is
different from the context in which it originally appeared, resulting in
spurious substitution failures for constructs that are valid in one context but
not the other, such as the use of an enclosing class's "this" pointer).
This patch switches us to use a different strategy: as before, we use the
declared type of the operator() to form the type of the conversion function and
invoker, but we now populate that type as part of return type deduction for the
conversion function. And the invoker is now treated as simply being an
implementation detail of building the conversion function, and isn't given
special treatment by template argument deduction for the conversion function
any more.
llvm-svn: 321683
The way to fix an undefined-template warning is to add lines to the header file that defines the template pattern. We should suppress the warnings when the template pattern is in a system header because we don't expect users to edit those.
llvm-svn: 321665
Summary:
Previsouly clang tried instantiating member initializers even if ctor
body was skipped, this caused spurious errors (see the test).
Reviewers: sepavloff, klimek
Reviewed By: sepavloff
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D41492
llvm-svn: 321520
Summary:
- Fixed an assert in Sema::InstantiateFunctionDefinition and added
support for instantiating a function template with skipped body.
- Properly call setHasSkippedBody for FunctionTemplateDecl passed to
Sema::ActOnSkippedFunctionBody.
Reviewers: sepavloff, bkramer
Reviewed By: sepavloff
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D41237
llvm-svn: 321174
whether they have an initializer.
We cannot distinguish between a declaration of a variable template
specialization and a definition of one that lacks an initializer without this,
and would previously mistake the latter for the former.
llvm-svn: 319605
In order to identify the copy deduction candidate, I considered two approaches:
- attempt to determine whether an implicit guide is a copy deduction candidate by checking certain properties of its subsituted parameter during overload-resolution.
- using one of the many bits (WillHaveBody) from FunctionDecl (that CXXDeductionGuideDecl inherits from) that are otherwise irrelevant for deduction guides
After some brittle gymnastics w the first strategy, I settled on the second, although to avoid confusion and to give that bit a better name, i turned it into a member of an anonymous union.
Given this identification 'bit', the tweak to overload resolution was a simple reordering of the deduction guide checks (in SemaOverload.cpp::isBetterOverloadCandidate), in-line with Jason Merrill's p0620r0 drafting which made it into the working paper. Concordant with that, I made sure the copy deduction candidate is always added.
References:
See https://bugs.llvm.org/show_bug.cgi?id=34970
See http://wg21.link/p0620r0
llvm-svn: 316292
instantiation declarations if they are usable from constant expressions.
We are permitted to instantiate in these cases, and required to do so in order
to have an initializer available for use within constant evaluation.
llvm-svn: 316136
When declaring an entity in the "purview" of a module, it's never a
redeclaration of an entity in the purview of a default module or in no module
("in the global module"). Don't consider those other declarations as possible
redeclaration targets if they're not visible, and reject any cases where we
pick a prior visible declaration that violates this rule.
This reinstates r315251 and r315256, reverted in r315309 and r315308
respectively, tweaked to avoid triggering a linkage calculation when declaring
implicit special members (this exposed our pre-existing issue with typedef
names for linkage changing the linkage of types whose linkage has already been
computed and cached in more cases). A testcase for that regression has been
added in r315366.
llvm-svn: 315379
When declaring an entity in the "purview" of a module, it's never a
redeclaration of an entity in the purview of a default module or in no module
("in the global module"). Don't consider those other declarations as possible
redeclaration targets if they're not visible, and reject any cases where we
pick a prior visible declaration that violates this rule.
llvm-svn: 315251
This implements the proposed approach in https://github.com/itanium-cxx-abi/cxx-abi/issues/33
This reinstates r313827, reverted in r313856, with a fix for the 'out-of-bounds
enumeration value' ubsan error in that change.
llvm-svn: 313955
move constructor.
Previously user-defined reduction initializer was considered as an
assignment expression, not as initializer. Fixed this by treating the
initializer expression as an initializer.
llvm-svn: 312638
the class becoming complete and its inline methods being parsed.
This replaces the hack of using the "late parsed template" flag to track member
functions with bodies we've not parsed yet; instead we now use the "will have
body" flag, which carries the desired implication that the function declaration
*is* a definition, and that we've just not parsed its body yet.
llvm-svn: 310776
declarations that are owned but unconditionally visible.
This allows us to set declarations as visible even if they have a local owning
module, without losing information. In turn, that means that our Objective-C
support can keep on incorrectly assuming the "hidden" bit on the declaration is
the whole story with regard to name visibility. This will also be useful once
we support the C++ Modules TS export semantics.
Objective-C name visibility is still incorrect in any case where the "hidden"
bit is not the complete story: for instance, in Objective-C++ the set of
visible categories will be wrong during template instantiation, and with local
submodule visibility enabled it will be wrong when building modules. Fixing that
will require a major overhaul of how visibility is handled for Objective-C (and
particularly for categories).
llvm-svn: 306075
While a function body is being parsed, the function declaration is not considered
as a definition because it does not have a body yet. In some cases it leads to
incorrect interpretation, the case is presented in
https://bugs.llvm.org/show_bug.cgi?id=14785:
```
template<typename T> struct Somewhat {
void internal() const {}
friend void operator+(int const &, Somewhat<T> const &) {}
};
void operator+(int const &, Somewhat<char> const &x) { x.internal(); }
```
When statement `x.internal()` in the body of global `operator+` is parsed, the type
of `x` must be completed, so the instantiation of `Somewhat<char>` is started. It
instantiates the declaration of `operator+` defined inline, and makes a check for
redefinition. The check does not detect another definition because the declaration
of `operator+` is still not defining as does not have a body yet.
To solves this problem the function `isThisDeclarationADefinition` considers
a function declaration as a definition if it has flag `WillHaveBody` set.
This change fixes PR14785.
Differential Revision: https://reviews.llvm.org/D30375
This is a recommit of 305379, reverted in 305381, with small changes.
llvm-svn: 305903
While a function body is being parsed, the function declaration is not considered
as a definition because it does not have a body yet. In some cases it leads to
incorrect interpretation, the case is presented in
https://bugs.llvm.org/show_bug.cgi?id=14785:
```
template<typename T> struct Somewhat {
void internal() const {}
friend void operator+(int const &, Somewhat<T> const &) {}
};
void operator+(int const &, Somewhat<char> const &x) { x.internal(); }
```
When statement `x.internal()` in the body of global `operator+` is parsed, the type
of `x` must be completed, so the instantiation of `Somewhat<char>` is started. It
instantiates the declaration of `operator+` defined inline, and makes a check for
redefinition. The check does not detect another definition because the declaration
of `operator+` is still not defining as does not have a body yet.
To solves this problem the function `isThisDeclarationADefinition` considers
a function declaration as a definition if it has flag `WillHaveBody` set.
This change fixes PR14785.
Differential Revision: https://reviews.llvm.org/D30375
llvm-svn: 305379
RecursiveASTVisitor was not properly recursing through a
SubstTemplateTypeParmTypes, resulting in crashes in pack expansion where we
couldn't always find an unexpanded pack within a pack expansion.
We also have an issue where substitution of deduced template arguments for an
implicit deduction guide creates the "impossible" case of naming a
non-dependent member of the current instantiation, but within a specialization
that is actually instantiated from a different (partial/explicit)
specialization of the template. We resolve this by declaring that constructors
that do so can only be used to deduce specializations of the primary template.
I'm running this past CWG to see if people agree this is the right thing to do.
llvm-svn: 304862
This fixes the bug: https://bugs.llvm.org/show_bug.cgi?id=32638
int main()
{
[](auto x) noexcept(noexcept(x)) { } (0);
}
In the above code, prior to this patch, when substituting into the noexcept expression, i.e. transforming the DeclRefExpr that represents 'x' - clang attempts to capture 'x' because Sema's CurContext is still pointing to the pattern FunctionDecl (i.e. the templated-decl set in FinishTemplateArgumentDeduction) which does not match the substituted 'x's DeclContext, which leads to an attempt to capture and an assertion failure.
We fix this by adjusting Sema's CurContext to point to the substituted FunctionDecl under which the noexcept specifier's argument should be transformed, and so the ParmVarDecl that 'x' refers to has the same declcontext and no capture is attempted.
I briefly investigated whether the SwitchContext should occur right after VisitMethodDecl creates the new substituted FunctionDecl, instead of only during instantiating the exception specification - but seeing no other code that seemed to rely on that, I decided to leave it just for the duration of the exception specification instantiation.
llvm-svn: 302507
- also replace direct equality checks against the ConstantEvaluated enumerator with isConstantEvaluted(), in anticipation of adding finer granularity to the various ConstantEvaluated contexts and reinstating certain restrictions on where lambda expressions can occur in C++17.
- update the clang tablegen backend that uses these Enumerators, and add the relevant scope where needed.
llvm-svn: 299316
GCC has the alloc_align attribute, which is similar to assume_aligned, except the attribute's parameter is the index of the integer parameter that needs aligning to.
Differential Revision: https://reviews.llvm.org/D29599
llvm-svn: 299117
Correct class-template deprecation behavior
Based on the comment in the test, and my reading of the standard, a deprecated warning should be issued in the following case:
template<typename T> [[deprecated]] class Foo{}; Foo<int> f;
This was not the case, because the ClassTemplateSpecializationDecl creation did not also copy the deprecated attribute.
Note: I did NOT audit the complete set of attributes to see WHICH ones should be copied, so instead I simply copy ONLY the deprecated attribute.
Previous DiffRev: https://reviews.llvm.org/D27486, was reverted.
This patch fixes the issues brought up here by the reverter: https://reviews.llvm.org/rL298410
Differential Revision: https://reviews.llvm.org/D31245
llvm-svn: 298634
Based on the comment in the test, and my reading of the standard, a deprecated warning should be issued in the following case:
template<typename T> [[deprecated]] class Foo{}; Foo<int> f;
This was not the case, because the ClassTemplateSpecializationDecl creation did not also copy the deprecated attribute.
Note: I did NOT audit the complete set of attributes to see WHICH ones should be copied, so instead I simply copy ONLY the deprecated attribute.
Differential Revision: https://reviews.llvm.org/D27486
llvm-svn: 298410
case where the class template has a parameter pack.
Checking of the template arguments expects an "as-written" template argument
list, which in particular does not have any parameter packs. So flatten the
packs into separate arguments before passing them in.
llvm-svn: 295710
template deduction guides for class template argument deduction.
Ensure that we have a local instantiation scope for tracking the instantiated
parameters. Additionally, unusually, we're substituting at depth 1 and leaving
depth 0 alone; make sure that we don't reduce template parameter depth by 2 for
inner parameters in the process. (This is probably also broken for alias
templates in the case where they're expanded within a dependent context, but
this patch doesn't fix that.)
llvm-svn: 295696
Summary: Previously the cleanups (e.g. dtor calls) are inserted into the
outer scope (e.g. function body scope), instead of it's own scope. After
the fix, the cleanups are inserted right after getting the size value.
This fixes pr30306.
Reviewers: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D24333
llvm-svn: 295123
such guides below explicit ones, and ensure that references to the class's
template parameters are not treated as forwarding references.
We make a few tweaks to the wording in the current standard:
1) The constructor parameter list is copied faithfully to the deduction guide,
without losing default arguments or a varargs ellipsis (which the standard
wording loses by omission).
2) If the class template declares no constructors, we add a T() -> T<...> guide
(which will only ever work if T has default arguments for all non-pack
template parameters).
3) If the class template declares nothing that looks like a copy or move
constructor, we add a T(T<...>) -> T<...> guide.
#2 and #3 follow from the "pretend we had a class type with these constructors"
philosophy for deduction guides.
llvm-svn: 295007
FindInstantiatedDecl or passing it to RebuildMemberExpr.
This fixes PR30361.
rdar://problem/17341274
Differential Revision: https://reviews.llvm.org/D24969
llvm-svn: 293678
non-template function instantiated from a friend declaration in a class
template from TSK_ImplicitInstantiation to TSK_Undeclared.
It doesn't make sense for a non-template function to be flagged as being
instantiated from a template; that property really belongs to the entity
as a whole and not an individual declaration of it. There's some history
here:
* r137934 started marking these functions as instantiations in order to
work around an issue where we might instantiate a class template while
we're still parsing its member definitions, and would otherwise fail
to instantiate the friend definition
* r177003 fixed the same issue but for friend templates, but did so by
making the friends claim to be definitions even before we'd parsed
their actual bodies; this made the r137934 change redundant
* r293558 worked around a problem caused by the marking of a non-template
function as a template instantiation in r137934
This change reverts the code changes from r293358 and r137934 and retains
all the tests.
llvm-svn: 293367
Fixes a crash in modules where the template class decl becomes the most recent
decl in the redeclaration chain and forcing the template instantiator try to
instantiate the friend declaration, rather than the template definition.
In practice, A::list<int> produces a TemplateSpecializationType
A::__1::list<int, allocator<type-parameter-0-0> >' failing to replace to
subsitute the default argument to allocator<int>.
Kudos Richard Smith (D28399).
llvm-svn: 291753
This flag serves no purpose other than to prevent us walking through a type to
check whether it contains an 'auto' specifier; this duplication of information
is error-prone, does not appear to provide any performance benefit, and will
become less practical once we support C++1z deduced class template types and
eventually constrained types from the Concepts TS.
No functionality change intended.
llvm-svn: 291737
`diagnose_if` can be used to have clang emit either warnings or errors
for function calls that meet user-specified conditions. For example:
```
constexpr int foo(int a)
__attribute__((diagnose_if(a > 10, "configurations with a > 10 are "
"expensive.", "warning")));
int f1 = foo(9);
int f2 = foo(10); // warning: configuration with a > 10 are expensive.
int f3 = foo(f2);
```
It currently only emits diagnostics in cases where the condition is
guaranteed to always be true. So, the following code will emit no
warnings:
```
constexpr int bar(int a) {
foo(a);
return 0;
}
constexpr int i = bar(10);
```
We hope to support optionally emitting diagnostics for cases like that
(and emitting runtime checks) in the future.
Release notes will appear shortly. :)
Differential Revision: https://reviews.llvm.org/D27424
llvm-svn: 291418
Summary:
Replace some old code that probably pre-dated the change to delay
emission of dllexported code until after the closing brace of the
outermost record type. Only uninstantiated default argument expressions
need to be handled now. It is enough to instantiate default argument
expressions when instantiating dllexported default ctors. This also
fixes some double-diagnostic issues in this area.
Fixes PR31500
Reviewers: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D28274
llvm-svn: 291045
to make reference to template parameters. This is only a partial
implementation; we retain the restriction that the argument must not be
type-dependent, since it's unclear how that would work given the existence of
other language rules requiring an exact type match in this context, even for
type-dependent cases (a question has been raised on the core reflector).
llvm-svn: 290647
This change introduces UsingPackDecl as a marker for the set of UsingDecls
produced by pack expansion of a single (unresolved) using declaration. This is
not strictly necessary (we just need to be able to map from the original using
declaration to its expansions somehow), but it's useful to maintain the
invariant that each declaration reference instantiates to refer to one
declaration.
This is a re-commit of r290080 (reverted in r290092) with a fix for a
use-after-lifetime bug.
llvm-svn: 290203
This change introduces UsingPackDecl as a marker for the set of UsingDecls
produced by pack expansion of a single (unresolved) using declaration. This is
not strictly necessary (we just need to be able to map from the original using
declaration to its expansions somehow), but it's useful to maintain the
invariant that each declaration reference instantiates to refer to one
declaration.
llvm-svn: 290080
* a dependent non-type using-declaration within a function template can be
valid, as it can refer to an enumerator, so don't reject it in the template
definition
* we can partially substitute into a dependent using-declaration if it appears
within a (local class in a) generic lambda within a function template, which
means an UnresolvedUsing*Decl doesn't necessarily instantiate to a UsingDecl.
llvm-svn: 290071
Summary:
clang-tidy checks frequently use source ranges of functions.
The source range of constructors and destructors in template instantiations
is currently a single token.
The factory method for constructors and destructors does not allow the
end source location to be specified.
Set end location manually after creating instantiation.
Reviewers: aaron.ballman, rsmith, arphaman
Subscribers: arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D26849
llvm-svn: 288025
During template instantiation, we currently fall back to just calling
Sema::SubstExpr for enable_if attributes that aren't value-dependent or
type-dependent. Since Sema::SubstExpr strips off any implicit casts
we've added to an expression, it's possible that this behavior will
leave us with an enable_if condition that's just a DeclRefExpr.
Conditions like that deeply confuse Sema::CheckEnableIf.
llvm-svn: 287187
Only look for a variable's value in the constant expression evaluation activation frame, if the variable was indeed declared in that frame, otherwise it might be a constant expression and be usable within a nested local scope or emit an error.
void f(char c) {
struct X {
static constexpr char f() {
return c; // error gracefully here as opposed to crashing.
}
};
int I = X::f();
}
llvm-svn: 286748
1) Merge and demote variable definitions when we find a redefinition in
MergeVarDecls, not only when we find one in AddInitializerToDecl (we only reach
the second case if it's the addition of the initializer itself that converts an
existing declaration into a definition).
2) When rebuilding a redeclaration chain for a variable, if we merge two
definitions together, mark the definitions as merged so the retained definition
is made visible whenever the demoted definition would have been.
Original commit message (from r283882):
[modules] PR28752: Do not instantiate variable declarations which are not visible.
Original patch by Vassil Vassilev! Changes listed above are mine.
llvm-svn: 284284
Original message:
"[modules] PR28752: Do not instantiate variable declarations which are not visible.
https://reviews.llvm.org/D24508
Patch developed in collaboration with Richard Smith!"
llvm-svn: 284008
Summary:
This is possible now that MapVector supports move-only values.
Depends on D25404.
Reviewers: timshen
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D25405
llvm-svn: 283766
within the instantiation of that same specialization. This could previously
happen for eagerly-instantiated function templates, variable templates,
exception specifications, default arguments, and a handful of other cases.
We still have an issue here for default template arguments that recursively
make use of themselves and likewise for substitution into the type of a
non-type template parameter, but in those cases we're producing a different
entity each time, so they should instead be caught by the instantiation depth
limit. However, currently we will typically run out of stack before we reach
it. :(
llvm-svn: 280190
to DiagnoseUninstantiableTemplate, teach hasVisibleDefinition to correctly
determine whether a function definition is visible, and mark both the function
and the template as visible when merging function template definitions to
provide hasVisibleDefinition with the relevant information.
The change to always pass the right declaration as the PatternDef to
DiagnoseUninstantiableTemplate also caused those checks to happen before other
diagnostics in InstantiateFunctionDefinition, giving worse diagnostics for the
same situations, so I sunk the relevant diagnostics into
DiagnoseUninstantiableTemplate. Those parts of this patch are based on changes
in reviews.llvm.org/D23492 by Vassil Vassilev.
This reinstates r279486, reverted in r279500, with a fix to
DiagnoseUninstantiableTemplate to only mark uninstantiable explicit
instantiation declarations as invalid if we actually diagnosed them. (When we
trigger an explicit instantiation of a class member from an explicit
instantiation declaration for the class, it's OK if there is no corresponding
definition and we certainly don't want to mark the member invalid in that
case.) This previously caused a build failure during bootstrap.
llvm-svn: 279557
to DiagnoseUninstantiableTemplate, teach hasVisibleDefinition to correctly
determine whether a function definition is visible, and mark both the function
and the template as visible when merging function template definitions to
provide hasVisibleDefinition with the relevant information.
The change to always pass the right declaration as the PatternDef to
DiagnoseUninstantiableTemplate also caused those checks to happen before other
diagnostics in InstantiateFunctionDefinition, giving worse diagnostics for the
same situations, so I sunk the relevant diagnostics into
DiagnoseUninstantiableTemplate. Those parts of this patch are based on changes
in reviews.llvm.org/D23492 by Vassil Vassilev.
llvm-svn: 279486