Revert various template unreachability code I committed accidentally.
r148774, r148775, r148776, r148777 llvm-svn: 148780
This commit is contained in:
parent
c46534a0cd
commit
0f2ae78980
|
@ -721,7 +721,7 @@ void CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B,
|
|||
}
|
||||
|
||||
const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
|
||||
if (Dtor && cast<FunctionType>(Dtor->getType())->getNoReturnAttr())
|
||||
if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr())
|
||||
Block = createNoReturnBlock();
|
||||
else
|
||||
autoCreateBlock();
|
||||
|
@ -750,12 +750,13 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
|
|||
// Before virtual bases destroy direct base objects.
|
||||
for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
|
||||
BE = RD->bases_end(); BI != BE; ++BI) {
|
||||
if (!BI->isVirtual())
|
||||
if (const CXXRecordDecl *CD = BI->getType()->getAsCXXRecordDecl())
|
||||
if (!CD->hasTrivialDestructor()) {
|
||||
autoCreateBlock();
|
||||
appendBaseDtor(Block, BI);
|
||||
}
|
||||
if (!BI->isVirtual()) {
|
||||
const CXXRecordDecl *CD = BI->getType()->getAsCXXRecordDecl();
|
||||
if (!CD->hasTrivialDestructor()) {
|
||||
autoCreateBlock();
|
||||
appendBaseDtor(Block, BI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First destroy member objects.
|
||||
|
@ -864,7 +865,7 @@ LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD,
|
|||
|
||||
// Check if type is a C++ class with non-trivial destructor.
|
||||
if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
|
||||
if (CD->hasDefinition() && !CD->hasTrivialDestructor()) {
|
||||
if (!CD->hasTrivialDestructor()) {
|
||||
// Add the variable to scope
|
||||
Scope = createOrReuseLocalScope(Scope);
|
||||
Scope->addVar(VD);
|
||||
|
|
|
@ -782,7 +782,8 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
|
|||
return;
|
||||
|
||||
// For code in dependent contexts, we'll do this at instantiation time.
|
||||
bool Dependent = cast<DeclContext>(D)->isDependentContext();
|
||||
if (cast<DeclContext>(D)->isDependentContext())
|
||||
return;
|
||||
|
||||
if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) {
|
||||
// Flush out any possibly unreachable diagnostics.
|
||||
|
@ -825,7 +826,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
|
|||
// Construct the analysis context with the specified CFG build options.
|
||||
|
||||
// Emit delayed diagnostics.
|
||||
if (!fscope->PossiblyUnreachableDiags.empty() && !Dependent) {
|
||||
if (!fscope->PossiblyUnreachableDiags.empty()) {
|
||||
bool analyzed = false;
|
||||
|
||||
// Register the expressions with the CFGBuilder.
|
||||
|
@ -873,7 +874,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
|
|||
|
||||
|
||||
// Warning: check missing 'return'
|
||||
if (P.enableCheckFallThrough && !Dependent) {
|
||||
if (P.enableCheckFallThrough) {
|
||||
const CheckFallThroughDiagnostics &CD =
|
||||
(isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
|
||||
: CheckFallThroughDiagnostics::MakeForFunction(D));
|
||||
|
@ -894,7 +895,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
|
|||
}
|
||||
|
||||
// Check for thread safety violations
|
||||
if (P.enableThreadSafetyAnalysis && !Dependent) {
|
||||
if (P.enableThreadSafetyAnalysis) {
|
||||
SourceLocation FL = AC.getDecl()->getLocation();
|
||||
thread_safety::ThreadSafetyReporter Reporter(S, FL);
|
||||
thread_safety::runThreadSafetyAnalysis(AC, Reporter);
|
||||
|
|
|
@ -73,21 +73,17 @@ void test() {
|
|||
(*array_ptr)[3] = 1; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
|
||||
}
|
||||
|
||||
// FIXME: we should see the next note only 3 times and the following warning once, not twice
|
||||
// since it is independent of the template parameter 'I'.
|
||||
template <int I> struct S {
|
||||
char arr[I]; // expected-note 4 {{declared here}}
|
||||
char arr[I]; // expected-note 2 {{declared here}}
|
||||
};
|
||||
template <int I> void f() {
|
||||
S<3> s;
|
||||
s.arr[4] = 0; // expected-warning 2 {{array index 4 is past the end of the array (which contains 3 elements)}}
|
||||
s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (which contains 3 elements)}} \
|
||||
expected-warning {{array index 3 is past the end of the array (which contains 3 elements)}}
|
||||
s.arr[4] = 0; // expected-warning {{array index 4 is past the end of the array (which contains 3 elements)}}
|
||||
s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (which contains 3 elements)}}
|
||||
}
|
||||
|
||||
void test_templates() {
|
||||
f<5>(); // expected-note {{in instantiation}}
|
||||
f<3>(); // expected-note {{in instantiation}}
|
||||
}
|
||||
|
||||
#define SIZE 10
|
||||
|
|
|
@ -98,24 +98,6 @@ void test_unreachable_templates_harness() {
|
|||
test_unreachable_templates<TestUnreachableB>();
|
||||
}
|
||||
|
||||
// Do warn about non-dependent unreachable code in templates
|
||||
// Warn even if the template is never instantiated
|
||||
|
||||
template<typename T> void test_non_dependent_unreachable_templates() {
|
||||
TestUnreachableA::foo();
|
||||
isUnreachable(); // expected-warning {{will never be executed}}
|
||||
}
|
||||
|
||||
// Warn only once even if the template is instantiated multiple times
|
||||
|
||||
template<typename T> void test_non_dependent_unreachable_templates2() {
|
||||
TestUnreachableA::foo();
|
||||
isUnreachable(); // expected-warning {{will never be executed}}
|
||||
}
|
||||
|
||||
template void test_non_dependent_unreachable_templates2<int>();
|
||||
template void test_non_dependent_unreachable_templates2<long>();
|
||||
|
||||
// Do warn about explict template specializations, as they represent
|
||||
// actual concrete functions that somebody wrote.
|
||||
|
||||
|
@ -125,19 +107,3 @@ template <> void funcToSpecialize<int>() {
|
|||
dead(); // expected-warning {{will never be executed}}
|
||||
}
|
||||
|
||||
// Ensure we don't regress a fix involving undefined bases to template
|
||||
// destructors when computing the CFG for unreachable code analysis
|
||||
template<int> struct imp;
|
||||
template<int a>
|
||||
struct aligned_storage : imp<a> {
|
||||
~aligned_storage() { }
|
||||
};
|
||||
|
||||
// is this valid?
|
||||
template<typename T>
|
||||
class outer {
|
||||
class inner;
|
||||
void func() {
|
||||
inner t;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue