@@ -152,6 +152,19 @@ EHScopeStack::getInnermostActiveNormalCleanup() const {
152152 return stable_end ();
153153}
154154
155+ static bool FunctionCanThrow (const FunctionDecl *D) {
156+ if (!D) {
157+ return true ;
158+ }
159+
160+ const auto *Proto = D->getType ()->getAs <FunctionProtoType>();
161+ if (!Proto) {
162+ // Function proto is not found, we conservatively assume throwing.
163+ return true ;
164+ }
165+ return !isNoexceptExceptionSpec (Proto->getExceptionSpecType ()) ||
166+ Proto->canThrow () != CT_Cannot;
167+ }
155168
156169void *EHScopeStack::pushCleanup (CleanupKind Kind, size_t Size) {
157170 char *Buffer = allocate (EHCleanupScope::getSizeForCleanupSize (Size));
@@ -191,7 +204,9 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
191204 // consistent with MSVC's behavior, except in the presence of -EHa.
192205 // Check getInvokeDest() to generate llvm.seh.scope.begin() as needed.
193206 if (CGF->getLangOpts ().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
194- CGF->getTarget ().getCXXABI ().isMicrosoft () && CGF->getInvokeDest ())
207+ CGF->getTarget ().getCXXABI ().isMicrosoft () &&
208+ FunctionCanThrow (dyn_cast<FunctionDecl>(CGF->CurFuncDecl )) &&
209+ CGF->getInvokeDest ())
195210 CGF->EmitSehCppScopeBegin ();
196211
197212 return Scope->getCleanupBuffer ();
@@ -784,7 +799,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,
784799 cleanupFlags.setIsEHCleanupKind ();
785800
786801 // Under -EHa, invoke seh.scope.end() to mark scope end before dtor
787- bool IsEHa = getLangOpts ().EHAsynch && !Scope.isLifetimeMarker ();
802+ bool IsEHa = getLangOpts ().EHAsynch && !Scope.isLifetimeMarker () &&
803+ FunctionCanThrow (dyn_cast<FunctionDecl>(CurFuncDecl));
788804 const EHPersonality &Personality = EHPersonality::get (*this );
789805 if (!RequiresNormalCleanup) {
790806 // Mark CPP scope end for passed-by-value Arg temp
0 commit comments