From 6f78f7469d0c8d32f9a1a4a16e05d9099004f345 Mon Sep 17 00:00:00 2001 From: d00574627 Date: Thu, 1 Aug 2024 14:29:04 +0800 Subject: [PATCH] [BSC] buggfix destructor param --- clang/include/clang/AST/Decl.h | 10 +++++++ .../clang/Basic/BSC/DiagnosticBSCSemaKinds.td | 1 + clang/lib/Parse/ParseStmt.cpp | 2 +- clang/lib/Sema/BSC/SemaBSCDestructor.cpp | 17 ++++++++--- clang/lib/Sema/SemaDecl.cpp | 1 + .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +++ .../invalid_destructor_param_num.cbs | 14 +++++++++ .../destructor/warn_destructor.cbs | 30 +++++++++++++++---- 8 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 clang/test/BSC/Negative/OwnedStruct/destructor/invalid_destructor_param_num.cbs diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index bea9d50af49c..150d3016dc69 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1328,6 +1328,9 @@ private: APValue *evaluateValueImpl(SmallVectorImpl &Notes, bool IsConstantInitialization) const; +#if ENABLE_BSC + bool IsDefInTopLevelSwitchBlock = false; +#endif public: /// Return the already-evaluated value of this variable's /// initializer, or NULL if the value is not yet known. Returns pointer @@ -1524,6 +1527,13 @@ public: NonParmVarDeclBits.EscapingByref = true; } +#if ENABLE_BSC + bool isDefInTopLevelSwitchBlock() {return IsDefInTopLevelSwitchBlock;} + void setDefInTopLevelSwitchBlock(bool V) { + IsDefInTopLevelSwitchBlock = V; + } +#endif + /// Determines if this variable's alignment is dependent. bool hasDependentAlignment() const; diff --git a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td index 56cfda788b4d..a486fc23d137 100644 --- a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td +++ b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td @@ -117,6 +117,7 @@ def err_struct_member_redeclared : Error<"struct member cannot be redeclared">; // BSC Destructor def invalid_param_for_destructor : Error<"the parameter of destructor must be '%0 this'">; +def invalid_param_num_for_destructor : Error<"destructor can only have one parameter">; def err_destructor_call : Error<"destructor %0 cannot be called directly">; def err_assignment_in_destructor : Error<"'this' cannot be moved in destructor">; def warn_destructor_execute : Warning<"the destructor may be not executed">, diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 4e7997ae90ab..988864d47316 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -391,7 +391,7 @@ Default: SemiError = "break"; #if ENABLE_BSC Actions.CollectDestructMap(Res.get(), getCurScope(), - getCurScope()->getFnParent()); + getCurScope()->getBreakParent()); #endif break; case tok::kw_return: // C99 6.8.6.4: return-statement diff --git a/clang/lib/Sema/BSC/SemaBSCDestructor.cpp b/clang/lib/Sema/BSC/SemaBSCDestructor.cpp index e3df72991659..36b3c05d8cdb 100644 --- a/clang/lib/Sema/BSC/SemaBSCDestructor.cpp +++ b/clang/lib/Sema/BSC/SemaBSCDestructor.cpp @@ -469,13 +469,16 @@ public: } } } + for (auto *C : compoundStmt->children()) { Stmt *SS = const_cast(C); if (DeclStmt *StmtDecl = dyn_cast(SS)) { for (auto *SD : StmtDecl->decls()) { - if (isa(SD) && - IsVarDeclWithOwnedStructureType(cast(SD))) { - VarDecls.insert(VarDecls.begin(), cast(SD)); + if (auto VD = dyn_cast(SD)) { + bool InTopLevelSwitchBlock = VD->isDefInTopLevelSwitchBlock(); + if (IsVarDeclWithOwnedStructureType(VD) && !InTopLevelSwitchBlock) { + VarDecls.insert(VarDecls.begin(), VD); + } } } } @@ -611,7 +614,6 @@ void Sema::CheckBSCDestructorDeclarator(FunctionDecl *NewFD) { } if (NewFD->getNumParams() == 0) { - // Diag(NewFD->getLocation(), diag::err_destructor_no_param); Diag(NewFD->getLocation(), diag::invalid_param_for_destructor) << TypeName; NewFD->setInvalidDecl(); return; @@ -634,6 +636,13 @@ void Sema::CheckBSCDestructorDeclarator(FunctionDecl *NewFD) { diag::invalid_param_for_destructor) << TypeName; NewFD->setInvalidDecl(); + return; + } + + if (NewFD->getNumParams() > 1) { + Diag(NewFD->getLocation(), diag::invalid_param_num_for_destructor); + NewFD->setInvalidDecl(); + return; } } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index deb86f7fb754..26529cfdd17e 100755 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14270,6 +14270,7 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { getCurScope()->getParent() && (getCurScope()->getParent()->getFlags() & Scope::SwitchScope)) { Diag(VD->getLocation(), diag::warn_destructor_execute); + VD->setDefInTopLevelSwitchBlock(true); } } #endif diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index aa3da74f0fb2..7a1855f2d226 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1130,6 +1130,10 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, D->getLocation(), D->getIdentifier(), DI->getType(), DI, D->getStorageClass()); +#if ENABLE_BSC + Var->setDefInTopLevelSwitchBlock(D->isDefInTopLevelSwitchBlock()); +#endif + // In ARC, infer 'retaining' for variables of retainable type. if (SemaRef.getLangOpts().ObjCAutoRefCount && SemaRef.inferObjCARCLifetime(Var)) diff --git a/clang/test/BSC/Negative/OwnedStruct/destructor/invalid_destructor_param_num.cbs b/clang/test/BSC/Negative/OwnedStruct/destructor/invalid_destructor_param_num.cbs new file mode 100644 index 000000000000..3b28bf0ea999 --- /dev/null +++ b/clang/test/BSC/Negative/OwnedStruct/destructor/invalid_destructor_param_num.cbs @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -verify %s + +owned struct A { + ~A(A this, int x) { // expected-error {{destructor can only have one parameter}} + } + +}; + + +owned struct B { + ~B(int x,int y) { // expected-error {{the parameter of destructor must be 'B this'}} + } + +}; \ No newline at end of file diff --git a/clang/test/BSC/Negative/OwnedStruct/destructor/warn_destructor.cbs b/clang/test/BSC/Negative/OwnedStruct/destructor/warn_destructor.cbs index 729fe9410c6f..423c65d24ddf 100644 --- a/clang/test/BSC/Negative/OwnedStruct/destructor/warn_destructor.cbs +++ b/clang/test/BSC/Negative/OwnedStruct/destructor/warn_destructor.cbs @@ -1,27 +1,47 @@ // RUN: %clang_cc1 -verify %s +// RUN: %clang %s -o %test.output +// RUN: %test.output +// RUN: %clang -rewrite-bsc %s -o %t-rw.c +// RUN: %clang %t-rw.c -o %t-rw.output +// RUN: %t-rw.output +int y = 0; owned struct A { public: ~A(A this){ + y++; } }; - int test_switch(void) { + int test_switch() { A a ={}; int xx = 1; switch(xx) { - A b ; // expected-warning {{the destructor may be not executed}} + A b = {}; // expected-warning {{the destructor may be not executed}} case 1: { A c ={}; break; } - + } + return 0; +} + +int test_switch1() { + A a ={}; + int xx = 1; + switch(xx) { + A b1 = {}; // expected-warning {{the destructor may be not executed}} + case 1: { + A c ={}; + return 1; + } } return 0; } int main(void) { - A a= {}; - return 0; + test_switch(); + test_switch1(); + return y-4; } -- Gitee