@@ -1803,7 +1803,7 @@ static void CheckConstexprCtorInitializer(Sema &SemaRef,
1803
1803
static bool
1804
1804
CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
1805
1805
SmallVectorImpl<SourceLocation> &ReturnStmts,
1806
- SourceLocation &Cxx1yLoc) {
1806
+ SourceLocation &Cxx1yLoc, SourceLocation &Cxx2aLoc ) {
1807
1807
// - its function-body shall be [...] a compound-statement that contains only
1808
1808
switch (S->getStmtClass()) {
1809
1809
case Stmt::NullStmtClass:
@@ -1840,7 +1840,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
1840
1840
CompoundStmt *CompStmt = cast<CompoundStmt>(S);
1841
1841
for (auto *BodyIt : CompStmt->body()) {
1842
1842
if (!CheckConstexprFunctionStmt(SemaRef, Dcl, BodyIt, ReturnStmts,
1843
- Cxx1yLoc))
1843
+ Cxx1yLoc, Cxx2aLoc ))
1844
1844
return false;
1845
1845
}
1846
1846
return true;
@@ -1858,11 +1858,11 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
1858
1858
1859
1859
IfStmt *If = cast<IfStmt>(S);
1860
1860
if (!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getThen(), ReturnStmts,
1861
- Cxx1yLoc))
1861
+ Cxx1yLoc, Cxx2aLoc ))
1862
1862
return false;
1863
1863
if (If->getElse() &&
1864
1864
!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getElse(), ReturnStmts,
1865
- Cxx1yLoc))
1865
+ Cxx1yLoc, Cxx2aLoc ))
1866
1866
return false;
1867
1867
return true;
1868
1868
}
@@ -1881,7 +1881,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
1881
1881
for (Stmt *SubStmt : S->children())
1882
1882
if (SubStmt &&
1883
1883
!CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
1884
- Cxx1yLoc))
1884
+ Cxx1yLoc, Cxx2aLoc ))
1885
1885
return false;
1886
1886
return true;
1887
1887
@@ -1896,10 +1896,30 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
1896
1896
for (Stmt *SubStmt : S->children())
1897
1897
if (SubStmt &&
1898
1898
!CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
1899
- Cxx1yLoc))
1899
+ Cxx1yLoc, Cxx2aLoc ))
1900
1900
return false;
1901
1901
return true;
1902
1902
1903
+ case Stmt::CXXTryStmtClass:
1904
+ if (Cxx2aLoc.isInvalid())
1905
+ Cxx2aLoc = S->getBeginLoc();
1906
+ for (Stmt *SubStmt : S->children()) {
1907
+ if (SubStmt &&
1908
+ !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts,
1909
+ Cxx1yLoc, Cxx2aLoc))
1910
+ return false;
1911
+ }
1912
+ return true;
1913
+
1914
+ case Stmt::CXXCatchStmtClass:
1915
+ // Do not bother checking the language mode (already covered by the
1916
+ // try block check).
1917
+ if (!CheckConstexprFunctionStmt(SemaRef, Dcl,
1918
+ cast<CXXCatchStmt>(S)->getHandlerBlock(),
1919
+ ReturnStmts, Cxx1yLoc, Cxx2aLoc))
1920
+ return false;
1921
+ return true;
1922
+
1903
1923
default:
1904
1924
if (!isa<Expr>(S))
1905
1925
break;
@@ -1920,6 +1940,8 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
1920
1940
///
1921
1941
/// \return true if the body is OK, false if we have diagnosed a problem.
1922
1942
bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
1943
+ SmallVector<SourceLocation, 4> ReturnStmts;
1944
+
1923
1945
if (isa<CXXTryStmt>(Body)) {
1924
1946
// C++11 [dcl.constexpr]p3:
1925
1947
// The definition of a constexpr function shall satisfy the following
@@ -1930,22 +1952,35 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
1930
1952
// C++11 [dcl.constexpr]p4:
1931
1953
// In the definition of a constexpr constructor, [...]
1932
1954
// - its function-body shall not be a function-try-block;
1933
- Diag(Body->getBeginLoc(), diag::err_constexpr_function_try_block)
1955
+ //
1956
+ // This restriction is lifted in C++2a, as long as inner statements also
1957
+ // apply the general constexpr rules.
1958
+ Diag(Body->getBeginLoc(),
1959
+ !getLangOpts().CPlusPlus2a
1960
+ ? diag::ext_constexpr_function_try_block_cxx2a
1961
+ : diag::warn_cxx17_compat_constexpr_function_try_block)
1934
1962
<< isa<CXXConstructorDecl>(Dcl);
1935
- return false;
1936
1963
}
1937
1964
1938
- SmallVector<SourceLocation, 4> ReturnStmts;
1939
-
1940
1965
// - its function-body shall be [...] a compound-statement that contains only
1941
1966
// [... list of cases ...]
1942
- CompoundStmt *CompBody = cast<CompoundStmt>(Body);
1943
- SourceLocation Cxx1yLoc;
1944
- for (auto *BodyIt : CompBody->body()) {
1945
- if (!CheckConstexprFunctionStmt(*this, Dcl, BodyIt, ReturnStmts, Cxx1yLoc))
1967
+ //
1968
+ // Note that walking the children here is enough to properly check for
1969
+ // CompoundStmt and CXXTryStmt body.
1970
+ SourceLocation Cxx1yLoc, Cxx2aLoc;
1971
+ for (Stmt *SubStmt : Body->children()) {
1972
+ if (SubStmt &&
1973
+ !CheckConstexprFunctionStmt(*this, Dcl, SubStmt, ReturnStmts,
1974
+ Cxx1yLoc, Cxx2aLoc))
1946
1975
return false;
1947
1976
}
1948
1977
1978
+ if (Cxx2aLoc.isValid())
1979
+ Diag(Cxx2aLoc,
1980
+ getLangOpts().CPlusPlus2a
1981
+ ? diag::warn_cxx17_compat_constexpr_body_invalid_stmt
1982
+ : diag::ext_constexpr_body_invalid_stmt_cxx2a)
1983
+ << isa<CXXConstructorDecl>(Dcl);
1949
1984
if (Cxx1yLoc.isValid())
1950
1985
Diag(Cxx1yLoc,
1951
1986
getLangOpts().CPlusPlus14
0 commit comments