@@ -41,8 +41,19 @@ along with GCC; see the file COPYING3. If not see
4141
4242using namespace gcc ::jit;
4343
44+ /* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */
45+ #define DECL_C_BIT_FIELD (NODE ) \
46+ (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE )) == 1 )
47+
48+ /* This is needed as the function is used by the `size_int` macro. */
49+ tree
50+ size_int_kind (poly_int64 number, enum size_type_kind kind);
51+
4452/* Attribute handling. */
4553
54+ static tree handle_packed_attribute (tree *, tree, tree, int , bool *);
55+ static tree handle_aligned_attribute (tree *node, tree name, tree args,
56+ int flags, bool *no_add_attrs);
4657static tree handle_alias_attribute (tree *, tree, tree, int , bool *);
4758static tree handle_always_inline_attribute (tree *, tree, tree, int ,
4859 bool *);
@@ -79,6 +90,16 @@ static tree ignore_attribute (tree *, tree, tree, int, bool *);
7990#define ATTR_EXCL (name, function, type, variable ) \
8091 { name, function, type, variable }
8192
93+ /* Define attributes that are mutually exclusive with one another. */
94+ extern const struct attribute_spec ::exclusions attr_aligned_exclusions[] =
95+ {
96+ /* Attribute name exclusion applies to:
97+ function, type, variable */
98+ ATTR_EXCL (" aligned" , true , false , false ),
99+ ATTR_EXCL (" packed" , true , false , false ),
100+ ATTR_EXCL (NULL , false , false , false )
101+ };
102+
82103/* Define attributes that are mutually exclusive with one another. */
83104static const struct attribute_spec ::exclusions attr_noreturn_exclusions[] =
84105{
@@ -171,6 +192,9 @@ static const attribute_spec jit_gnu_attributes[] =
171192 affects_type_identity, handler, exclude } */
172193 { " alias" , 1 , 1 , true , false , false , false ,
173194 handle_alias_attribute, NULL },
195+ { " aligned" , 0 , 1 , false , false , false , false ,
196+ handle_aligned_attribute,
197+ attr_aligned_exclusions },
174198 { " always_inline" , 0 , 0 , true , false , false , false ,
175199 handle_always_inline_attribute,
176200 attr_always_inline_exclusions },
@@ -188,6 +212,7 @@ static const attribute_spec jit_gnu_attributes[] =
188212 handle_leaf_attribute, NULL },
189213 { " malloc" , 0 , 0 , true , false , false , false ,
190214 handle_malloc_attribute, attr_alloc_exclusions },
215+ { " may_alias" , 0 , 0 , false , true , false , false , NULL , NULL },
191216 { " noreturn" , 0 , 0 , true , false , false , false ,
192217 handle_noreturn_attribute,
193218 attr_noreturn_exclusions },
@@ -200,6 +225,9 @@ static const attribute_spec jit_gnu_attributes[] =
200225 handle_nonnull_attribute, NULL },
201226 { " nothrow" , 0 , 0 , true , false , false , false ,
202227 handle_nothrow_attribute, NULL },
228+ { " packed" , 0 , 0 , false , false , false , false ,
229+ handle_packed_attribute,
230+ attr_aligned_exclusions },
203231 { " patchable_function_entry" , 1 , 2 , true , false , false , false ,
204232 handle_patchable_function_entry_attribute,
205233 NULL },
@@ -221,15 +249,15 @@ static const attribute_spec jit_gnu_attributes[] =
221249 handle_type_generic_attribute, NULL },
222250 { " transaction_pure" , 0 , 0 , false , true , true , false ,
223251 handle_transaction_pure_attribute, NULL },
224- { " used" , 0 , 0 , true , false , false , false ,
225- handle_used_attribute, NULL },
226- { " visibility" , 1 , 1 , false , false , false , false ,
227- handle_visibility_attribute, NULL },
228- { " weak" , 0 , 0 , true , false , false , false ,
229- handle_weak_attribute, NULL },
252+ { " used" , 0 , 0 , true , false , false , false ,
253+ handle_used_attribute, NULL },
254+ { " visibility" , 1 , 1 , false , false , false , false ,
255+ handle_visibility_attribute, NULL },
256+ { " weak" , 0 , 0 , true , false , false , false ,
257+ handle_weak_attribute, NULL },
230258 /* For internal use only. The leading '*' both prevents its usage in
231259 source code and signals that it may be overridden by machine tables. */
232- { " *tm regparm" , 0 , 0 , false , true , true , false ,
260+ { " *tm regparm" , 0 , 0 , false , true , true , false ,
233261 ignore_attribute, NULL },
234262};
235263
@@ -1159,6 +1187,290 @@ handle_retain_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
11591187 return NULL_TREE ;
11601188}
11611189
1190+ /* Handle a "packed" attribute; arguments as in
1191+ struct attribute_spec.handler. */
1192+
1193+ static tree
1194+ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1195+ int flags, bool *no_add_attrs)
1196+ {
1197+ if (TYPE_P (*node))
1198+ {
1199+ if (!(flags & (int ) ATTR_FLAG_TYPE_IN_PLACE ))
1200+ {
1201+ warning (OPT_Wattributes,
1202+ " %qE attribute ignored for type %qT" , name, *node);
1203+ *no_add_attrs = true ;
1204+ }
1205+ else
1206+ TYPE_PACKED (*node) = 1 ;
1207+ }
1208+ else if (TREE_CODE (*node) == FIELD_DECL )
1209+ {
1210+ if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
1211+ /* Still pack bitfields. */
1212+ && ! DECL_C_BIT_FIELD (*node))
1213+ warning (OPT_Wattributes,
1214+ " %qE attribute ignored for field of type %qT" ,
1215+ name, TREE_TYPE (*node));
1216+ else
1217+ DECL_PACKED (*node) = 1 ;
1218+ }
1219+ /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
1220+ used for DECL_REGISTER. It wouldn't mean anything anyway.
1221+ We can't set DECL_PACKED on the type of a TYPE_DECL, because
1222+ that changes what the typedef is typing. */
1223+ else
1224+ {
1225+ warning (OPT_Wattributes, " %qE attribute ignored" , name);
1226+ *no_add_attrs = true ;
1227+ }
1228+
1229+ return NULL_TREE ;
1230+ }
1231+
1232+
1233+ static int
1234+ check_user_alignment (const_tree align, bool objfile, bool warn_zero)
1235+ {
1236+ if (error_operand_p (align))
1237+ return -1 ;
1238+
1239+ if (TREE_CODE (align) != INTEGER_CST
1240+ || !INTEGRAL_TYPE_P (TREE_TYPE (align)))
1241+ {
1242+ error (" requested alignment is not an integer constant" );
1243+ return -1 ;
1244+ }
1245+
1246+ if (integer_zerop (align))
1247+ {
1248+ if (warn_zero)
1249+ warning (OPT_Wattributes,
1250+ " requested alignment %qE is not a positive power of 2" ,
1251+ align);
1252+ return -1 ;
1253+ }
1254+
1255+ /* Log2 of the byte alignment ALIGN. */
1256+ int log2align;
1257+ if (tree_int_cst_sgn (align) == -1
1258+ || (log2align = tree_log2 (align)) == -1 )
1259+ {
1260+ error (" requested alignment %qE is not a positive power of 2" ,
1261+ align);
1262+ return -1 ;
1263+ }
1264+
1265+ if (objfile)
1266+ {
1267+ unsigned maxalign = MAX_OFILE_ALIGNMENT / BITS_PER_UNIT ;
1268+ if (!tree_fits_uhwi_p (align) || tree_to_uhwi (align) > maxalign)
1269+ {
1270+ error (" requested alignment %qE exceeds object file maximum %u" ,
1271+ align, maxalign);
1272+ return -1 ;
1273+ }
1274+ }
1275+
1276+ if (log2align >= HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT )
1277+ {
1278+ error (" requested alignment %qE exceeds maximum %u" ,
1279+ align, 1U << (HOST_BITS_PER_INT - LOG2_BITS_PER_UNIT - 1 ));
1280+ return -1 ;
1281+ }
1282+
1283+ return log2align;
1284+ }
1285+
1286+ /* Common codes shared by handle_warn_if_not_aligned_attribute and
1287+ handle_aligned_attribute. */
1288+
1289+ static tree
1290+ common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
1291+ bool *no_add_attrs,
1292+ bool warn_if_not_aligned_p)
1293+ {
1294+ tree decl = NULL_TREE ;
1295+ tree *type = NULL ;
1296+ bool is_type = false ;
1297+ tree align_expr;
1298+
1299+ /* The last (already pushed) declaration with all validated attributes
1300+ merged in or the current about-to-be-pushed one if one hasn't been
1301+ yet. */
1302+ tree last_decl = node[1 ] ? node[1 ] : *node;
1303+
1304+ if (args)
1305+ {
1306+ align_expr = TREE_VALUE (args);
1307+ /* FIXME: Uncomment this code or find a way to use `default_conversion`.
1308+ if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
1309+ && TREE_CODE (align_expr) != FUNCTION_DECL)
1310+ align_expr = default_conversion (align_expr);*/
1311+ }
1312+ else
1313+ align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT );
1314+
1315+ if (DECL_P (*node))
1316+ {
1317+ decl = *node;
1318+ type = &TREE_TYPE (decl);
1319+ is_type = TREE_CODE (*node) == TYPE_DECL ;
1320+ }
1321+ else if (TYPE_P (*node))
1322+ type = node, is_type = true ;
1323+
1324+ /* True to consider invalid alignments greater than MAX_OFILE_ALIGNMENT. */
1325+ bool objfile = (TREE_CODE (*node) == FUNCTION_DECL
1326+ || (VAR_P (*node) && TREE_STATIC (*node)));
1327+ /* Log2 of specified alignment. */
1328+ int pow2align = check_user_alignment (align_expr, objfile,
1329+ /* warn_zero = */ true );
1330+ if (pow2align == -1 )
1331+ {
1332+ *no_add_attrs = true ;
1333+ return NULL_TREE ;
1334+ }
1335+
1336+ /* The alignment in bits corresponding to the specified alignment. */
1337+ unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT ;
1338+
1339+ /* The alignment of the current declaration and that of the last
1340+ pushed declaration, determined on demand below. */
1341+ unsigned curalign = 0 ;
1342+ unsigned lastalign = 0 ;
1343+
1344+ /* True when SET_DECL_ALIGN() should be called for the decl when
1345+ *NO_ADD_ATTRS is false. */
1346+ bool set_align = true ;
1347+ if (is_type)
1348+ {
1349+ if ((flags & (int ) ATTR_FLAG_TYPE_IN_PLACE ))
1350+ /* OK, modify the type in place. */ ;
1351+ /* If we have a TYPE_DECL, then copy the type, so that we
1352+ don't accidentally modify a builtin type. See pushdecl. */
1353+ else if (decl && TREE_TYPE (decl) != error_mark_node
1354+ && DECL_ORIGINAL_TYPE (decl) == NULL_TREE )
1355+ {
1356+ tree tt = TREE_TYPE (decl);
1357+ *type = build_variant_type_copy (*type);
1358+ DECL_ORIGINAL_TYPE (decl) = tt;
1359+ TYPE_NAME (*type) = decl;
1360+ TREE_USED (*type) = TREE_USED (decl);
1361+ TREE_TYPE (decl) = *type;
1362+ }
1363+ else
1364+ *type = build_variant_type_copy (*type);
1365+
1366+ if (warn_if_not_aligned_p)
1367+ {
1368+ SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
1369+ warn_if_not_aligned_p = false ;
1370+ }
1371+ else
1372+ {
1373+ SET_TYPE_ALIGN (*type, bitalign);
1374+ TYPE_USER_ALIGN (*type) = 1 ;
1375+ }
1376+ }
1377+ else if (! VAR_OR_FUNCTION_DECL_P (decl)
1378+ && TREE_CODE (decl) != FIELD_DECL )
1379+ {
1380+ error (" alignment may not be specified for %q+D" , decl);
1381+ *no_add_attrs = true ;
1382+ }
1383+ else if (TREE_CODE (decl) == FUNCTION_DECL
1384+ && (((curalign = DECL_ALIGN (decl)) > bitalign)
1385+ | ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
1386+ {
1387+ /* Either a prior attribute on the same declaration or one
1388+ on a prior declaration of the same function specifies
1389+ stricter alignment than this attribute. */
1390+ bool note = (lastalign > curalign
1391+ || (lastalign == curalign
1392+ && (DECL_USER_ALIGN (last_decl)
1393+ > DECL_USER_ALIGN (decl))));
1394+ if (note)
1395+ curalign = lastalign;
1396+
1397+ curalign /= BITS_PER_UNIT ;
1398+ unsigned newalign = bitalign / BITS_PER_UNIT ;
1399+
1400+ auto_diagnostic_group d;
1401+ if ((DECL_USER_ALIGN (decl)
1402+ || DECL_USER_ALIGN (last_decl)))
1403+ {
1404+ if (warning (OPT_Wattributes,
1405+ " ignoring attribute %<%E (%u)%> because it conflicts "
1406+ " with attribute %<%E (%u)%>" ,
1407+ name, newalign, name, curalign)
1408+ && note)
1409+ inform (DECL_SOURCE_LOCATION (last_decl),
1410+ " previous declaration here" );
1411+ /* Only reject attempts to relax/override an alignment
1412+ explicitly specified previously and accept declarations
1413+ that appear to relax the implicit function alignment for
1414+ the target. Both increasing and increasing the alignment
1415+ set by -falign-functions setting is permitted. */
1416+ *no_add_attrs = true ;
1417+ }
1418+ else if (!warn_if_not_aligned_p)
1419+ {
1420+ /* Do not fail for attribute warn_if_not_aligned. Otherwise,
1421+ silently avoid applying the alignment to the declaration
1422+ because it's implicitly satisfied by the target. Apply
1423+ the attribute nevertheless so it can be retrieved by
1424+ __builtin_has_attribute. */
1425+ set_align = false ;
1426+ }
1427+ }
1428+ else if (DECL_USER_ALIGN (decl)
1429+ && DECL_ALIGN (decl) > bitalign)
1430+ /* C++-11 [dcl.align/4]:
1431+
1432+ When multiple alignment-specifiers are specified for an
1433+ entity, the alignment requirement shall be set to the
1434+ strictest specified alignment.
1435+
1436+ This formally comes from the c++11 specification but we are
1437+ doing it for the GNU attribute syntax as well. */
1438+ *no_add_attrs = true ;
1439+ else if (warn_if_not_aligned_p
1440+ && TREE_CODE (decl) == FIELD_DECL
1441+ && !DECL_C_BIT_FIELD (decl))
1442+ {
1443+ SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
1444+ warn_if_not_aligned_p = false ;
1445+ set_align = false ;
1446+ }
1447+
1448+ if (warn_if_not_aligned_p)
1449+ {
1450+ error (" %<warn_if_not_aligned%> may not be specified for %q+D" ,
1451+ decl);
1452+ *no_add_attrs = true ;
1453+ }
1454+ else if (!is_type && !*no_add_attrs && set_align)
1455+ {
1456+ SET_DECL_ALIGN (decl, bitalign);
1457+ DECL_USER_ALIGN (decl) = 1 ;
1458+ }
1459+
1460+ return NULL_TREE ;
1461+ }
1462+
1463+ /* Handle a "aligned" attribute; arguments as in
1464+ struct attribute_spec.handler. */
1465+
1466+ tree
1467+ handle_aligned_attribute (tree *node, tree name, tree args,
1468+ int flags, bool *no_add_attrs)
1469+ {
1470+ return common_handle_aligned_attribute (node, name, args, flags,
1471+ no_add_attrs, false );
1472+ }
1473+
11621474/* (end of attribute-handling). */
11631475
11641476/* Language-dependent contents of a type. */
0 commit comments