@@ -1554,21 +1554,54 @@ class cppfront
1554
1554
1555
1555
// -----------------------------------------------------------------------
1556
1556
//
1557
- auto is_it_pointer_declaration (declaration_sym const * decl , int deref_cnt = 0 , int addr_cnt = 0 ) -> bool {
1558
- if (!decl || !decl-> declaration )
1557
+ auto is_it_pointer_declaration (const std::unique_ptr<unqualified_id_node>& unqual , int deref_cnt = 0 , int addr_cnt = 0 ) -> bool {
1558
+ if (!unqual )
1559
1559
return false ;
1560
- if (addr_cnt>deref_cnt )
1560
+ if (!unqual-> pointer_declarators . empty () )
1561
1561
return true ;
1562
+ auto decl = sema.get_declaration_of (*unqual->identifier , true );
1563
+
1564
+ if (!decl || !decl->declaration )
1565
+ return false ;
1566
+
1567
+ if (auto * fun = std::get_if<declaration_node::function>(&decl->declaration ->type )) {
1568
+ if (auto * ret_id_expr = std::get_if<function_type_node::id>(&(*fun)->returns )) {
1569
+ if (auto * unqual = std::get_if<id_expression_node::unqualified>(&(*ret_id_expr)->id )){
1570
+ return is_it_pointer_declaration (*unqual, deref_cnt, addr_cnt);
1571
+ }
1572
+ }
1573
+ }
1574
+
1575
+ if (auto * obj_id_expr = std::get_if<declaration_node::object>(&decl->declaration ->type )) {
1576
+ if (auto * unqual = std::get_if<id_expression_node::unqualified>(&(*obj_id_expr)->id )){
1577
+ return is_it_pointer_declaration (*unqual, deref_cnt, addr_cnt);
1578
+ }
1579
+ }
1580
+
1581
+ if (decl->initializer && decl->initializer ->suspicious_initialization ) {
1582
+ auto init_decl = sema.get_declaration_of (*decl->initializer ->suspicious_initialization , true );
1583
+ if (init_decl && init_decl->declaration ) {
1584
+ if (auto * fun = std::get_if<declaration_node::function>(&init_decl->declaration ->type )) {
1585
+ if (auto * ret_id_expr = std::get_if<function_type_node::id>(&(*fun)->returns )) {
1586
+ if (auto * unqual = std::get_if<id_expression_node::unqualified>(&(*ret_id_expr)->id )){
1587
+ return is_it_pointer_declaration (*unqual, deref_cnt, addr_cnt);
1588
+ }
1589
+ }
1590
+ }
1591
+ }
1592
+ }
1562
1593
1563
1594
if (decl->declaration ->dereference ) {
1564
- auto deref = sema.get_declaration_of (*decl->declaration ->dereference );
1565
- return is_it_pointer_declaration (deref, deref_cnt+decl->declaration ->dereference_cnt , addr_cnt);
1595
+ auto deref = sema.get_declaration_of (*decl->declaration ->dereference , true );
1596
+ assert (deref && deref->declaration );
1597
+ return is_it_pointer_declaration (deref->declaration ->identifier , deref_cnt+decl->declaration ->dereference_cnt , addr_cnt);
1566
1598
} else if (decl->declaration ->address_of ) {
1567
- auto addr = sema.get_declaration_of (*decl->declaration ->address_of );
1568
- return is_it_pointer_declaration (addr, deref_cnt, addr_cnt+1 );
1599
+ auto addr = sema.get_declaration_of (*decl->declaration ->address_of , true );
1600
+ assert (addr && addr->declaration );
1601
+ return is_it_pointer_declaration (addr->declaration ->identifier , deref_cnt, addr_cnt+1 );
1569
1602
}
1570
1603
1571
- return (std::ssize (decl->declaration ->pointer_declarators ) + addr_cnt - deref_cnt) > 0 ;
1604
+ return ((decl-> declaration -> identifier ? std::ssize (decl->declaration ->identifier -> pointer_declarators ) : 0 ) + addr_cnt - deref_cnt) > 0 ;
1572
1605
};
1573
1606
1574
1607
// -----------------------------------------------------------------------
@@ -1596,26 +1629,32 @@ class cppfront
1596
1629
1597
1630
// if initialized by something suspicious (that we have no information about) we need to add cpp1 safety checks
1598
1631
add_safetycheck = !decl && needs_safetycheck;
1599
- if (is_it_pointer_declaration (decl )) {
1632
+ if (is_it_pointer_declaration (unqual )) {
1600
1633
if (n.ops .empty ()) {
1601
1634
last_postfix_expr_was_pointer = true ;
1602
1635
}
1603
1636
else
1604
1637
{
1605
- if (n.ops .front ().op ->type () == lexeme::PlusPlus ||
1606
- n.ops .front ().op ->type () == lexeme::MinusMinus ||
1607
- n.ops .front ().op ->type () == lexeme::LeftBracket
1608
- ) {
1638
+ auto op = [&](){
1639
+ if (n.ops .size () >= 2 && n.ops [0 ].op ->type () == lexeme::LeftParen) {
1640
+ return n.ops [1 ].op ;
1641
+ } else {
1642
+ return n.ops .front ().op ;
1643
+ }
1644
+ }();
1645
+ if (op->type () == lexeme::PlusPlus ||
1646
+ op->type () == lexeme::MinusMinus ||
1647
+ op->type () == lexeme::LeftBracket) {
1609
1648
errors.emplace_back (
1610
- n. ops . front (). op ->position (),
1611
- n. ops . front (). op ->to_string (true ) + " - pointer arithmetic is illegal - use std::span or gsl::span instead"
1649
+ op->position (),
1650
+ op->to_string (true ) + " - pointer arithmetic is illegal - use std::span or gsl::span instead"
1612
1651
);
1613
1652
violates_bounds_safety = true ;
1614
1653
}
1615
- else if (n. ops . front (). op ->type () == lexeme::Tilde) {
1654
+ else if (op->type () == lexeme::Tilde) {
1616
1655
errors.emplace_back (
1617
- n. ops . front (). op ->position (),
1618
- n. ops . front (). op ->to_string (true ) + " - pointer bitwise manipulation is illegal - use std::bit_cast to convert to raw bytes first"
1656
+ op->position (),
1657
+ op->to_string (true ) + " - pointer bitwise manipulation is illegal - use std::bit_cast to convert to raw bytes first"
1619
1658
);
1620
1659
}
1621
1660
}
@@ -2187,9 +2226,11 @@ class cppfront
2187
2226
}
2188
2227
else {
2189
2228
emit ( id_expr );
2190
- for (const auto pointer_declarator : n.declaration ->pointer_declarators ) {
2191
- printer.print_cpp2 (" " , pointer_declarator->position ());
2192
- emit (*pointer_declarator);
2229
+ if (unqid) {
2230
+ for (const auto pointer_declarator : (*unqid)->pointer_declarators ) {
2231
+ printer.print_cpp2 (" " , pointer_declarator->position ());
2232
+ emit (*pointer_declarator);
2233
+ }
2193
2234
}
2194
2235
}
2195
2236
@@ -2370,6 +2411,12 @@ class cppfront
2370
2411
auto & r = std::get<function_type_node::id>(n.returns );
2371
2412
assert (r);
2372
2413
emit (*r);
2414
+ if (auto * id = std::get_if<id_expression_node::unqualified>(&r->id )) {
2415
+ assert (*id);
2416
+ for (auto _ : (*id)->pointer_declarators ) {
2417
+ printer.print_cpp2 (" *" , n.position ());
2418
+ }
2419
+ }
2373
2420
}
2374
2421
2375
2422
else {
@@ -2570,8 +2617,11 @@ class cppfront
2570
2617
}
2571
2618
printer.preempt_position (n.position ());
2572
2619
emit ( *type );
2573
- for (auto _ : n.pointer_declarators ) {
2574
- printer.print_cpp2 (" *" , n.position ());
2620
+ if (auto * id = std::get_if<id_expression_node::unqualified>(&type->id )) {
2621
+ assert (*id);
2622
+ for (auto _ : (*id)->pointer_declarators ) {
2623
+ printer.print_cpp2 (" *" , n.position ());
2624
+ }
2575
2625
}
2576
2626
// one pointer is enough for now, pointer-to-function fun can be later
2577
2627
if (!n.initializer ) {
0 commit comments