@@ -269,4 +269,94 @@ void test_switch_cases() {
269
269
// case 0xFFFF'FFFF'FFFF:
270
270
// break;
271
271
}
272
+ }
273
+
274
+ // Test reference types - references to numeric types are considered numeric
275
+ void test_reference_types_basic () {
276
+ std::uint8_t l1 = 42 ;
277
+ std::uint32_t l2 = 100 ;
278
+ std::int8_t l3 = -5 ;
279
+ float l4 = 3 .14f ;
280
+
281
+ std::uint8_t &l5 = l1; // COMPLIANT
282
+ std::uint32_t &l6 = l2; // COMPLIANT
283
+ std::int8_t &l7 = l3; // COMPLIANT
284
+ float &l8 = l4; // COMPLIANT
285
+
286
+ // Reference types follow same rules as their referred types
287
+ u32 = l5; // COMPLIANT - widening of id-expression (reference)
288
+ u8 = l6; // NON_COMPLIANT - narrowing from reference
289
+ u8 = l7; // NON_COMPLIANT - different signedness from reference
290
+ s32 = l8; // NON_COMPLIANT - different type category from reference
291
+ }
292
+
293
+ void test_reference_types_function_parameters () {
294
+ std::uint8_t l1 = 42 ;
295
+ std::uint16_t l2 = 1000 ;
296
+
297
+ std::uint8_t &l3 = l1;
298
+ std::uint16_t &l4 = l2;
299
+
300
+ // Function calls with reference arguments
301
+ f1 (l3); // NON_COMPLIANT - widening conversion through reference
302
+ f2 (l4); // NON_COMPLIANT - narrowing conversion through reference
303
+ }
304
+
305
+ void test_reference_types_signedness () {
306
+ std::uint8_t l1 = 42 ;
307
+ std::int8_t l2 = -5 ;
308
+
309
+ std::uint8_t &l3 = l1;
310
+ std::int8_t &l4 = l2;
311
+
312
+ // Signedness violations through references
313
+ s8 = l3; // NON_COMPLIANT - different signedness through reference
314
+ u8 = l4; // NON_COMPLIANT - different signedness through reference
315
+ }
316
+
317
+ void test_reference_types_floating_point () {
318
+ float l1 = 3 .14f ;
319
+ double l2 = 2.718 ;
320
+ std::int32_t l3 = 42 ;
321
+
322
+ float &l4 = l1;
323
+ double &l5 = l2;
324
+ std::int32_t &l6 = l3;
325
+
326
+ // Type category violations through references
327
+ s32 = l4; // NON_COMPLIANT - different type category through reference
328
+ f = l5; // NON_COMPLIANT - different size through reference
329
+ f = l6; // NON_COMPLIANT - different type category through reference
330
+ }
331
+
332
+ void test_reference_types_expressions () {
333
+ std::uint8_t l1 = 42 ;
334
+ std::uint8_t l2 = 24 ;
335
+
336
+ std::uint8_t &l3 = l1;
337
+ std::uint8_t &l4 = l2;
338
+
339
+ // Expression results with references still follow expression rules
340
+ u8 = l3 + l4; // NON_COMPLIANT - addition promotes to int
341
+ s32 = l3 + l4; // COMPLIANT - promotion to int
342
+ }
343
+
344
+ // Test reference parameters in functions
345
+ void f13 (std::uint8_t &l1) {}
346
+ void f13 (std::uint16_t &l1) {}
347
+
348
+ void f14 (std::uint32_t l1) {}
349
+
350
+ void test_references () {
351
+ std::uint8_t l1 = 42 ;
352
+ std::uint16_t l2 = 1000 ;
353
+
354
+ f13 (l1); // COMPLIANT - exact match
355
+ f13 (l2); // COMPLIANT - exact match
356
+
357
+ std::uint16_t &l3 = l2;
358
+ f14 (l3); // NON_COMPLIANT - must be the same type, as non-overload-independent
359
+ std::uint64_t l4 = 1000 ;
360
+ std::uint64_t &l5 = l4;
361
+ f14 (l5); // NON_COMPLIANT - narrowing conversion through reference
272
362
}
0 commit comments