Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
2012-10-19 20:44:48 +08:00
|
|
|
// expected-no-diagnostics
|
Keep an explicit stack of function and block scopes, each element of
which has the label map, switch statement stack, etc. Previously, we
had a single set of maps in Sema (for the function) along with a stack
of block scopes. However, this lead to funky behavior with nested
functions, e.g., in the member functions of local classes.
The explicit-stack approach is far cleaner, and we retain a 1-element
cache so that we're not malloc/free'ing every time we enter a
function. Fixes PR6382.
Also, tweaked the unused-variable warning suppression logic to look at
errors within a given Scope rather than within a given function. The
prior code wasn't looking at the right number-of-errors count when
dealing with blocks, since the block's count would be deallocated
before we got to ActOnPopScope. This approach works with nested
blocks/functions, and gives tighter error recovery.
llvm-svn: 97518
2010-03-02 07:15:13 +08:00
|
|
|
|
|
|
|
namespace PR6382 {
|
|
|
|
int foo()
|
|
|
|
{
|
|
|
|
goto error;
|
|
|
|
{
|
|
|
|
struct BitPacker {
|
|
|
|
BitPacker() {}
|
|
|
|
};
|
|
|
|
BitPacker packer;
|
|
|
|
}
|
|
|
|
|
|
|
|
error:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2010-03-02 09:29:43 +08:00
|
|
|
|
|
|
|
namespace PR6383 {
|
|
|
|
void test (bool gross)
|
|
|
|
{
|
|
|
|
struct compare_and_set
|
|
|
|
{
|
|
|
|
void operator() (const bool inner, const bool gross = false)
|
|
|
|
{
|
|
|
|
// the code
|
|
|
|
}
|
|
|
|
} compare_and_set2;
|
|
|
|
|
|
|
|
compare_and_set2 (false, gross);
|
|
|
|
}
|
|
|
|
}
|
2010-04-28 05:10:04 +08:00
|
|
|
|
|
|
|
namespace Templates {
|
|
|
|
template<int Value>
|
|
|
|
void f() {
|
|
|
|
struct Inner {
|
|
|
|
static int getValue() { return Value; }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
Fix PR25627: constant expressions being odr-used in template arguments.
This patch ensures that clang processes the expression-nodes that are generated when disambiguating between types and expressions within template arguments as constant-expressions by installing the ConstantEvaluated ExpressionEvaluationContext just before attempting the disambiguation - and then making sure that Context carries through into ParseConstantExpression (by refactoring it out into a function that does not create its own EvaluationContext: ParseConstantExpressionInExprEvalContext)
Note, prior to this patch, trunk would correctly disambiguate and identify the expression as an expression - and while it would annotate the token with the expression - it would fail to complete the odr-use processing (specifically, failing to trigger Sema::UpdateMarkingForLValueToRValue as is done for all Constant Expressions, which would remove it from being considered odr-used). By installing the ConstantExpression Evaluation Context prior to disambiguation, and making sure it carries though, we ensure correct processing of the expression-node.
For e.g:
template<int> struct X { };
void f() {
const int N = 10;
X<N> x; // should be OK.
[] { return X<N>{}; }; // Should be OK - no capture - but clang errors!
}
See a related bug: https://bugs.llvm.org//show_bug.cgi?id=25627
In summary (and reiteration), the fix is as follows:
- Remove the EnteredConstantEvaluatedContext action from ParseTemplateArgumentList (relying on ParseTemplateArgument getting it right)
- Add the EnteredConstantEvaluatedContext action just prior to undergoing the disambiguating parse, and if the parse succeeds for an expression, carry the context though into a refactored version of ParseConstantExpression that does not create its own ExpressionEvaluationContext.
See https://reviews.llvm.org/D31588 for additional context regarding some of the more fragile and complicated approaches attempted, and Richard's feedback that eventually shaped the simpler and more robust rendition that is being committed.
Thanks Richard!
llvm-svn: 303492
2017-05-21 03:58:04 +08:00
|
|
|
|
|
|
|
namespace PR25627_dont_odr_use_local_consts {
|
|
|
|
template<int> struct X { X(); X(int); };
|
|
|
|
|
|
|
|
void foo() {
|
|
|
|
const int N = 10;
|
|
|
|
|
|
|
|
struct Local {
|
|
|
|
void f(X<N> = X<N>()) {} // OK
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|