bmoody created this revision. bmoody added a reviewer: rsmith. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Segfault occurs when the hack is applied to a function decl containing an unparsed default argument. Parser::HandleMemberFunctionDeclDelays was assuming that if a decl contains an unparsed default arg then it must also have an unparsed exception spec. This causes a read-from-wrong-union-member on FunctionTypeInfo::ExceptionSpecTokens, triggering a segfault later on when the pointer is used. Repository: rC Clang https://reviews.llvm.org/D65913 Files: clang/lib/Parse/ParseDeclCXX.cpp clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp Index: clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp =================================================================== --- clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp +++ clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp @@ -9,6 +9,7 @@ // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DPR28423 +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DDEFAULT_ARG // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=pair // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=priority_queue // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=stack @@ -48,7 +49,11 @@ #endif A member; #ifndef MSVC +#ifndef DEFAULT_ARG void swap(CLASS &other) noexcept(noexcept(swap(member, other.member))); +#else + void swap(CLASS &other, int = 0) noexcept(noexcept(swap(member, other.member))); +#endif #endif }; Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -2180,8 +2180,10 @@ LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); // Stash the exception-specification tokens in the late-pased method. - LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; - FTI.ExceptionSpecTokens = nullptr; + if (FTI.getExceptionSpecType() == EST_Unparsed) { + LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; + FTI.ExceptionSpecTokens = nullptr; + } // Push tokens for each parameter. Those that do not have // defaults will be NULL.
Index: clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp =================================================================== --- clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp +++ clang/test/SemaCXX/libstdcxx_pair_swap_hack.cpp @@ -9,6 +9,7 @@ // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DPR28423 +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DDEFAULT_ARG // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=pair // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=priority_queue // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=stack @@ -48,7 +49,11 @@ #endif A member; #ifndef MSVC +#ifndef DEFAULT_ARG void swap(CLASS &other) noexcept(noexcept(swap(member, other.member))); +#else + void swap(CLASS &other, int = 0) noexcept(noexcept(swap(member, other.member))); +#endif #endif }; Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -2180,8 +2180,10 @@ LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); // Stash the exception-specification tokens in the late-pased method. - LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; - FTI.ExceptionSpecTokens = nullptr; + if (FTI.getExceptionSpecType() == EST_Unparsed) { + LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; + FTI.ExceptionSpecTokens = nullptr; + } // Push tokens for each parameter. Those that do not have // defaults will be NULL.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits