@@ -76,10 +76,16 @@ static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A,
7676}
7777
7878template <typename FPGALoopAttrT>
79- static Attr *handleIntelFPGALoopAttr (Sema &S, const ParsedAttr &A) {
79+ static Attr *handleIntelFPGALoopAttr (Sema &S, Stmt *St, const ParsedAttr &A) {
8080 if (S.LangOpts .SYCLIsHost )
8181 return nullptr ;
8282
83+ if (!isa<ForStmt, CXXForRangeStmt, DoStmt, WhileStmt>(St)) {
84+ S.Diag (A.getLoc (), diag::err_attribute_wrong_decl_type_str)
85+ << A << " 'for', 'while', and 'do' statements" ;
86+ return nullptr ;
87+ }
88+
8389 unsigned NumArgs = A.getNumArgs ();
8490 if (NumArgs > 1 ) {
8591 S.Diag (A.getLoc (), diag::warn_attribute_too_many_arguments) << A << 1 ;
@@ -104,10 +110,16 @@ static Attr *handleIntelFPGALoopAttr(Sema &S, const ParsedAttr &A) {
104110
105111template <>
106112Attr *handleIntelFPGALoopAttr<SYCLIntelFPGADisableLoopPipeliningAttr>(
107- Sema &S, const ParsedAttr &A) {
113+ Sema &S, Stmt *St, const ParsedAttr &A) {
108114 if (S.LangOpts .SYCLIsHost )
109115 return nullptr ;
110116
117+ if (!isa<ForStmt, CXXForRangeStmt, DoStmt, WhileStmt>(St)) {
118+ S.Diag (A.getLoc (), diag::err_attribute_wrong_decl_type_str)
119+ << A << " 'for', 'while', and 'do' statements" ;
120+ return nullptr ;
121+ }
122+
111123 unsigned NumArgs = A.getNumArgs ();
112124 if (NumArgs > 0 ) {
113125 S.Diag (A.getLoc (), diag::warn_attribute_too_many_arguments) << A << 0 ;
@@ -270,7 +282,13 @@ CheckRedundantSYCLIntelFPGAIVDepAttrs(Sema &S, ArrayRef<const Attr *> Attrs) {
270282 }
271283}
272284
273- static Attr *handleIntelFPGAIVDepAttr (Sema &S, const ParsedAttr &A) {
285+ static Attr *handleIntelFPGAIVDepAttr (Sema &S, Stmt *St, const ParsedAttr &A) {
286+ if (!isa<ForStmt, CXXForRangeStmt, DoStmt, WhileStmt>(St)) {
287+ S.Diag (A.getLoc (), diag::err_attribute_wrong_decl_type_str)
288+ << A << " 'for', 'while', and 'do' statements" ;
289+ return nullptr ;
290+ }
291+
274292 unsigned NumArgs = A.getNumArgs ();
275293 if (NumArgs > 2 ) {
276294 S.Diag (A.getLoc (), diag::err_attribute_too_many_arguments) << A << 2 ;
@@ -284,10 +302,17 @@ static Attr *handleIntelFPGAIVDepAttr(Sema &S, const ParsedAttr &A) {
284302 NumArgs == 2 ? A.getArgAsExpr (1 ) : nullptr );
285303}
286304
287- static Attr *handleIntelFPGANofusionAttr (Sema &S, const ParsedAttr &A) {
305+ static Attr *handleIntelFPGANofusionAttr (Sema &S, Stmt *St,
306+ const ParsedAttr &A) {
288307 if (S.LangOpts .SYCLIsHost )
289308 return nullptr ;
290309
310+ if (!isa<ForStmt, CXXForRangeStmt, DoStmt, WhileStmt>(St)) {
311+ S.Diag (A.getLoc (), diag::err_attribute_wrong_decl_type_str)
312+ << A << " 'for', 'while', and 'do' statements" ;
313+ return nullptr ;
314+ }
315+
291316 unsigned NumArgs = A.getNumArgs ();
292317 if (NumArgs > 0 ) {
293318 S.Diag (A.getLoc (), diag::warn_attribute_too_many_arguments) << A << 0 ;
@@ -751,8 +776,17 @@ static Attr *handleLoopUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A,
751776 Expr *E = NumArgs ? A.getArgAsExpr (0 ) : nullptr ;
752777 if (A.getParsedKind () == ParsedAttr::AT_OpenCLUnrollHint)
753778 return S.BuildOpenCLLoopUnrollHintAttr (A, E);
754- else if (A.getParsedKind () == ParsedAttr::AT_LoopUnrollHint)
779+ else if (A.getParsedKind () == ParsedAttr::AT_LoopUnrollHint) {
780+ // FIXME: this should be hoisted up to the top level, but can't be placed
781+ // there until the opencl attribute has its parsing error converted into a
782+ // semantic error. See: Parser::ParseOpenCLUnrollHintAttribute().
783+ if (!isa<ForStmt, CXXForRangeStmt, DoStmt, WhileStmt>(St)) {
784+ S.Diag (A.getLoc (), diag::err_attribute_wrong_decl_type_str)
785+ << A << " 'for', 'while', and 'do' statements" ;
786+ return nullptr ;
787+ }
755788 return S.BuildLoopUnrollHintAttr (A, E);
789+ }
756790
757791 return nullptr ;
758792}
@@ -771,20 +805,22 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
771805 case ParsedAttr::AT_LoopHint:
772806 return handleLoopHintAttr (S, St, A, Range);
773807 case ParsedAttr::AT_SYCLIntelFPGAIVDep:
774- return handleIntelFPGAIVDepAttr (S, A);
808+ return handleIntelFPGAIVDepAttr (S, St, A);
775809 case ParsedAttr::AT_SYCLIntelFPGAInitiationInterval:
776- return handleIntelFPGALoopAttr<SYCLIntelFPGAInitiationIntervalAttr>(S, A);
810+ return handleIntelFPGALoopAttr<SYCLIntelFPGAInitiationIntervalAttr>(S, St,
811+ A);
777812 case ParsedAttr::AT_SYCLIntelFPGAMaxConcurrency:
778- return handleIntelFPGALoopAttr<SYCLIntelFPGAMaxConcurrencyAttr>(S, A);
813+ return handleIntelFPGALoopAttr<SYCLIntelFPGAMaxConcurrencyAttr>(S, St, A);
779814 case ParsedAttr::AT_SYCLIntelFPGALoopCoalesce:
780- return handleIntelFPGALoopAttr<SYCLIntelFPGALoopCoalesceAttr>(S, A);
815+ return handleIntelFPGALoopAttr<SYCLIntelFPGALoopCoalesceAttr>(S, St, A);
781816 case ParsedAttr::AT_SYCLIntelFPGADisableLoopPipelining:
782- return handleIntelFPGALoopAttr<SYCLIntelFPGADisableLoopPipeliningAttr>(S,
783- A);
817+ return handleIntelFPGALoopAttr<SYCLIntelFPGADisableLoopPipeliningAttr>(
818+ S, St, A);
784819 case ParsedAttr::AT_SYCLIntelFPGAMaxInterleaving:
785- return handleIntelFPGALoopAttr<SYCLIntelFPGAMaxInterleavingAttr>(S, A);
820+ return handleIntelFPGALoopAttr<SYCLIntelFPGAMaxInterleavingAttr>(S, St, A);
786821 case ParsedAttr::AT_SYCLIntelFPGASpeculatedIterations:
787- return handleIntelFPGALoopAttr<SYCLIntelFPGASpeculatedIterationsAttr>(S, A);
822+ return handleIntelFPGALoopAttr<SYCLIntelFPGASpeculatedIterationsAttr>(S, St,
823+ A);
788824 case ParsedAttr::AT_OpenCLUnrollHint:
789825 case ParsedAttr::AT_LoopUnrollHint:
790826 return handleLoopUnrollHint (S, St, A, Range);
@@ -797,7 +833,7 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
797833 case ParsedAttr::AT_Unlikely:
798834 return handleUnlikely (S, St, A, Range);
799835 case ParsedAttr::AT_SYCLIntelFPGANofusion:
800- return handleIntelFPGANofusionAttr (S, A);
836+ return handleIntelFPGANofusionAttr (S, St, A);
801837 default :
802838 // if we're here, then we parsed a known attribute, but didn't recognize
803839 // it as a statement attribute => it is declaration attribute
0 commit comments