Skip to content

Commit 6135600

Browse files
committed
[Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11
1 parent 82c5d35 commit 6135600

File tree

4 files changed

+28
-15
lines changed

4 files changed

+28
-15
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@ Bug Fixes to C++ Support
742742
- Fix a bug with checking constrained non-type template parameters for equivalence. Fixes (#GH77377).
743743
- Fix a bug where the last argument was not considered when considering the most viable function for
744744
explicit object argument member functions. Fixes (#GH92188).
745+
- Fix a C++11 crash when a non-const non-static member function is defined out-of-line with
746+
the ``constexpr`` specifier.
745747

746748
Bug Fixes to AST Handling
747749
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/DeclSpec.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
15271527

15281528
/// Retrieve the location of the 'const' qualifier.
15291529
SourceLocation getConstQualifierLoc() const {
1530-
assert(MethodQualifiers);
1531-
return MethodQualifiers->getConstSpecLoc();
1530+
return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
1531+
: SourceLocation();
15321532
}
15331533

15341534
/// Retrieve the location of the 'volatile' qualifier.
15351535
SourceLocation getVolatileQualifierLoc() const {
1536-
assert(MethodQualifiers);
1537-
return MethodQualifiers->getVolatileSpecLoc();
1536+
return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
1537+
: SourceLocation();
15381538
}
15391539

15401540
/// Retrieve the location of the 'restrict' qualifier.
15411541
SourceLocation getRestrictQualifierLoc() const {
1542-
assert(MethodQualifiers);
1543-
return MethodQualifiers->getRestrictSpecLoc();
1542+
return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
1543+
: SourceLocation();
15441544
}
15451545

15461546
/// Retrieve the location of the 'mutable' qualifier, if any.

clang/lib/Sema/SemaDecl.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9217,15 +9217,15 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
92179217
<< Idx << FDParam->getType()
92189218
<< NewFD->getParamDecl(Idx - 1)->getType();
92199219
} else if (FDisConst != NewFDisConst) {
9220-
SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
9221-
<< NewFDisConst << FD->getSourceRange().getEnd()
9222-
<< (NewFDisConst
9223-
? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
9224-
.getConstQualifierLoc())
9225-
: FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
9226-
.getRParenLoc()
9227-
.getLocWithOffset(1),
9228-
" const"));
9220+
auto DB = SemaRef.Diag(FD->getLocation(),
9221+
diag::note_member_def_close_const_match)
9222+
<< NewFDisConst << FD->getSourceRange().getEnd();
9223+
if (const auto &FTI = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
9224+
DB << FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
9225+
" const");
9226+
else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
9227+
ConstLoc.isValid())
9228+
DB << FixItHint::CreateRemoval(ConstLoc);
92299229
} else
92309230
SemaRef.Diag(FD->getLocation(),
92319231
IsMember ? diag::note_member_def_close_match

clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,14 @@ namespace {
154154
// FIXME: We should diagnose this prior to C++17.
155155
const int &r = A::n;
156156
}
157+
158+
#if __cplusplus < 201402L
159+
namespace ImplicitConstexprDef {
160+
struct A {
161+
void f(); // expected-note {{member declaration does not match because it is not const qualified}}
162+
};
163+
164+
constexpr void A::f() { } // expected-warning {{'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior}}
165+
// expected-error@-1 {{out-of-line definition of 'f' does not match any declaration in 'ImplicitConstexprDef::A'}}
166+
}
167+
#endif

0 commit comments

Comments
 (0)