From a8f9b49353bd2de590908e6d660c92fa1a87951a Mon Sep 17 00:00:00 2001 From: zhaoxuhui Date: Wed, 8 Mar 2023 09:54:00 +0800 Subject: [PATCH 1/2] [BSC] bugfix for calling without function name --- clang/lib/Parse/ParseExpr.cpp | 12 ++++++++++++ .../BSC/Method/Struct/struct_no_function_name.cbs | 11 +++++++++++ 2 files changed, 23 insertions(+) create mode 100644 clang/test/BSC/Method/Struct/struct_no_function_name.cbs diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 6fb1a7dba79a..a8bfbac9d7ff 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1046,6 +1046,10 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, QualType T = Actions.ConvertBSCScopeSpecToType( D, BSS.getBeginLoc(), false); // get scope type for BSC HasBSCScopeSpce = TryConsumeToken(tok::coloncolon); + if (!Tok.is(tok::identifier)) { + Diag(Tok, diag::err_expected_unqualified_id) << 0; + return ExprError(); + } return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, isVectorLiteral, NotPrimaryExpression, T, HasBSCScopeSpce); @@ -1063,6 +1067,10 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, QualType T = Actions.ConvertBSCScopeSpecToType( D, BSS.getBeginLoc(), false); // get scope type for BSC HasBSCScopeSpce = TryConsumeToken(tok::coloncolon); + if (!Tok.is(tok::identifier)) { + Diag(Tok, diag::err_expected_unqualified_id) << 0; + return ExprError(); + } return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, isVectorLiteral, NotPrimaryExpression, T, HasBSCScopeSpce); @@ -1560,6 +1568,10 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, QualType T = Actions.ConvertBSCScopeSpecToType( D, BSS.getBeginLoc(), false); // get scope type for BSC HasBSCScopeSpce = TryConsumeToken(tok::coloncolon); + if (!Tok.is(tok::identifier)) { + Diag(Tok, diag::err_expected_unqualified_id) << 0; + return ExprError(); + } return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, isVectorLiteral, NotPrimaryExpression, T, HasBSCScopeSpce); diff --git a/clang/test/BSC/Method/Struct/struct_no_function_name.cbs b/clang/test/BSC/Method/Struct/struct_no_function_name.cbs new file mode 100644 index 000000000000..b6326de9e866 --- /dev/null +++ b/clang/test/BSC/Method/Struct/struct_no_function_name.cbs @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -verify %s + +struct Foo { + int a; +}; + +int main() { + struct Foo foo = {.a = 1}; + int a = struct Foo::(&foo); // expected-error {{expected identifier}} + return a - 1; +} \ No newline at end of file -- Gitee From 9213e25f8a030b6209145657804109e9a23dda9f Mon Sep 17 00:00:00 2001 From: zhaoxuhui Date: Thu, 9 Mar 2023 10:22:13 +0800 Subject: [PATCH 2/2] fix review suggestions --- clang/include/clang/AST/Expr.h | 2 +- clang/include/clang/Parse/Parser.h | 9 ++-- clang/lib/Parse/ParseExpr.cpp | 75 ++++++++++++------------------ clang/lib/Sema/SemaExpr.cpp | 6 +-- 4 files changed, 41 insertions(+), 51 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index b19f98326eeb..c327014732ef 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -138,7 +138,7 @@ protected: friend class ASTStmtReader; // Sets dependence dircetly. public: - bool HasBSCScopeSpce = false; + bool HasBSCScopeSpec = false; QualType getType() const { return TR; } void setType(QualType t) { // In C++, the type of an expression is always adjusted so that it diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 3f6dc67f257c..9e8008926447 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1787,14 +1787,17 @@ private: UnaryExprOnly, PrimaryExprOnly }; + ExprResult ParseOptionalBSCScopeSpecifier( + CastParseKind ParseKind, bool isAddressOfOperand, bool &NotCastExpr, + TypeCastState isTypeCast, bool isVectorLiteral = false, + bool *NotPrimaryExpression = nullptr, bool HasBSCScopeSpec = false); ExprResult ParseCastExpression(CastParseKind ParseKind, - bool isAddressOfOperand, - bool &NotCastExpr, + bool isAddressOfOperand, bool &NotCastExpr, TypeCastState isTypeCast, bool isVectorLiteral = false, bool *NotPrimaryExpression = nullptr, QualType T = QualType(), - bool HasBSCScopeSpce = false); + bool HasBSCScopeSpec = false); ExprResult ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand = false, TypeCastState isTypeCast = NotTypeCast, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index a8bfbac9d7ff..22b280decae4 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -729,6 +729,26 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback { }; } +ExprResult Parser::ParseOptionalBSCScopeSpecifier( + CastParseKind ParseKind, bool isAddressOfOperand, bool &NotCastExpr, + TypeCastState isTypeCast, bool isVectorLiteral, bool *NotPrimaryExpression, + bool HasBSCScopeSpec) { + ParsingDeclSpec BSS(*this); + ParseBSCScopeSpecifiers(BSS); + ParsingDeclarator D(*this, BSS, DeclaratorContext::File); + D.setBSCScopeSpec(&BSS); + QualType T = Actions.ConvertBSCScopeSpecToType( + D, BSS.getBeginLoc(), false); // get scope type for BSC + HasBSCScopeSpec = TryConsumeToken(tok::coloncolon); + if (Tok.isNot(tok::identifier)) { + Diag(Tok, diag::err_expected_unqualified_id) << 0; + return ExprError(); + } + return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, + isTypeCast, isVectorLiteral, NotPrimaryExpression, + T, HasBSCScopeSpec); +} + /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse /// a unary-expression. /// @@ -913,7 +933,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, bool &NotCastExpr, TypeCastState isTypeCast, bool isVectorLiteral, bool *NotPrimaryExpression, - QualType T, bool HasBSCScopeSpce) { + QualType T, bool HasBSCScopeSpec) { ExprResult Res; tok::TokenKind SavedKind = Tok.getKind(); auto SavedType = PreferredType; @@ -1039,20 +1059,9 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, case tok::kw_enum: case tok::kw_struct: if (getLangOpts().BSC && FindUntil(tok::coloncolon)) { - ParsingDeclSpec BSS(*this); - ParseBSCScopeSpecifiers(BSS); - ParsingDeclarator D(*this, BSS, DeclaratorContext::File); - D.setBSCScopeSpec(&BSS); - QualType T = Actions.ConvertBSCScopeSpecToType( - D, BSS.getBeginLoc(), false); // get scope type for BSC - HasBSCScopeSpce = TryConsumeToken(tok::coloncolon); - if (!Tok.is(tok::identifier)) { - Diag(Tok, diag::err_expected_unqualified_id) << 0; - return ExprError(); - } - return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, - isTypeCast, isVectorLiteral, - NotPrimaryExpression, T, HasBSCScopeSpce); + return ParseOptionalBSCScopeSpecifier( + ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, + isVectorLiteral, NotPrimaryExpression, HasBSCScopeSpec); } // Fall through; this isn't a message send. LLVM_FALLTHROUGH; @@ -1060,20 +1069,9 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, // unqualified-id: identifier // constant: enumeration-constant if (getLangOpts().BSC && FindUntil(tok::coloncolon)) { - ParsingDeclSpec BSS(*this); - ParseBSCScopeSpecifiers(BSS); - ParsingDeclarator D(*this, BSS, DeclaratorContext::File); - D.setBSCScopeSpec(&BSS); - QualType T = Actions.ConvertBSCScopeSpecToType( - D, BSS.getBeginLoc(), false); // get scope type for BSC - HasBSCScopeSpce = TryConsumeToken(tok::coloncolon); - if (!Tok.is(tok::identifier)) { - Diag(Tok, diag::err_expected_unqualified_id) << 0; - return ExprError(); - } - return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, - isTypeCast, isVectorLiteral, - NotPrimaryExpression, T, HasBSCScopeSpce); + return ParseOptionalBSCScopeSpecifier( + ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, + isVectorLiteral, NotPrimaryExpression, HasBSCScopeSpec); } // Turn a potentially qualified name into a annot_typename or // annot_cxxscope if it would be valid. This handles things like x::y, etc. @@ -1561,20 +1559,9 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, #include "clang/Basic/OpenCLImageTypes.def" { if (getLangOpts().BSC && FindUntil(tok::coloncolon)) { - ParsingDeclSpec BSS(*this); - ParseBSCScopeSpecifiers(BSS); - ParsingDeclarator D(*this, BSS, DeclaratorContext::File); - D.setBSCScopeSpec(&BSS); - QualType T = Actions.ConvertBSCScopeSpecToType( - D, BSS.getBeginLoc(), false); // get scope type for BSC - HasBSCScopeSpce = TryConsumeToken(tok::coloncolon); - if (!Tok.is(tok::identifier)) { - Diag(Tok, diag::err_expected_unqualified_id) << 0; - return ExprError(); - } - return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, - isTypeCast, isVectorLiteral, - NotPrimaryExpression, T, HasBSCScopeSpce); + return ParseOptionalBSCScopeSpecifier( + ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, + isVectorLiteral, NotPrimaryExpression, HasBSCScopeSpec); } if (!getLangOpts().CPlusPlus) { Diag(Tok, diag::err_expected_expression); @@ -1858,7 +1845,7 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, // These can be followed by postfix-expr pieces. PreferredType = SavedType; if (Res.get()) - Res.get()->HasBSCScopeSpce = HasBSCScopeSpce; + Res.get()->HasBSCScopeSpec = HasBSCScopeSpec; Res = ParsePostfixExpressionSuffix(Res); if (getLangOpts().OpenCL) if (Expr *PostfixExpr = Res.get()) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8843c1f8d082..4dce16017717 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5785,7 +5785,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, : (IsExecConfig ? 3 /* kernel function (exec config) */ : 0 /* function */); bool isBSCInstanceFunc = false; - if (FDecl && !Fn->HasBSCScopeSpce) { + if (FDecl && !Fn->HasBSCScopeSpec) { BSCMethodDecl* MD = dyn_cast_or_null(FDecl); if (MD && MD->getHasThisParam()) { isBSCInstanceFunc = true; @@ -6621,7 +6621,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, ArrayRef Args, SourceLocation RParenLoc, Expr *Config, bool IsExecConfig, ADLCallKind UsesADL) { - bool HasBSCScopeSpce = Fn->HasBSCScopeSpce; + bool HasBSCScopeSpec = Fn->HasBSCScopeSpec; FunctionDecl *FDecl = dyn_cast_or_null(NDecl); unsigned BuiltinID = (FDecl ? FDecl->getBuiltinID() : 0); @@ -6663,7 +6663,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (Result.isInvalid()) return ExprError(); Fn = Result.get(); - Fn->HasBSCScopeSpce = HasBSCScopeSpce; + Fn->HasBSCScopeSpec = HasBSCScopeSpec; // Check for a valid function type, but only if it is not a builtin which // requires custom type checking. These will be handled by -- Gitee