@@ -1082,7 +1082,7 @@ class cppfront
1082
1082
1083
1083
in_definite_init = is_definite_initialization (n.identifier );
1084
1084
if (!in_definite_init && !in_parameter_list) {
1085
- if (auto decl = sema.get_local_declaration_of (*n.identifier );
1085
+ if (auto decl = sema.get_declaration_of (*n.identifier );
1086
1086
is_local_name &&
1087
1087
decl &&
1088
1088
// note pointer equality: if we're not in the actual declaration of n.identifier
@@ -1606,6 +1606,86 @@ class cppfront
1606
1606
}
1607
1607
}
1608
1608
1609
+ // Don't work yet, TODO: finalize deducing pointer types from parameter lists
1610
+ auto is_pointer_declaration (parameter_declaration_list_node const * decl_node, int deref_cnt, int addr_cnt) -> bool {
1611
+ return false ;
1612
+ }
1613
+
1614
+ auto is_pointer_declaration (declaration_node const * decl_node, int deref_cnt, int addr_cnt) -> bool {
1615
+ if (!decl_node) {
1616
+ return false ;
1617
+ }
1618
+ if (addr_cnt > deref_cnt) {
1619
+ return true ;
1620
+ }
1621
+
1622
+ return std::visit ([&](auto const & type){
1623
+ return is_pointer_declaration (type.get (), deref_cnt, addr_cnt);
1624
+ }, decl_node->type );
1625
+ }
1626
+
1627
+ auto is_pointer_declaration (function_type_node const * fun_node, int deref_cnt, int addr_cnt) -> bool {
1628
+ if (!fun_node) {
1629
+ return false ;
1630
+ }
1631
+ if (addr_cnt > deref_cnt) {
1632
+ return true ;
1633
+ }
1634
+
1635
+ return std::visit ([&]<typename T>(T const & type){
1636
+ if constexpr (std::is_same_v<T, std::monostate>) {
1637
+ return false ;
1638
+ } else {
1639
+ return is_pointer_declaration (type.get (), deref_cnt, addr_cnt);
1640
+ }
1641
+ }, fun_node->returns );
1642
+ }
1643
+
1644
+ auto is_pointer_declaration (type_id_node const * type_node, int deref_cnt, int addr_cnt) -> bool {
1645
+ if (!type_node) {
1646
+ return false ;
1647
+ }
1648
+ if (addr_cnt > deref_cnt) {
1649
+ return true ;
1650
+ }
1651
+
1652
+ if ( type_node->dereference_of ) {
1653
+ return is_pointer_declaration (type_node->dereference_of , deref_cnt + type_node->dereference_cnt , addr_cnt);
1654
+ } else if ( type_node->address_of ) {
1655
+ return is_pointer_declaration (type_node->address_of , deref_cnt, addr_cnt + 1 );
1656
+ }
1657
+
1658
+ int pointer_declarators_cnt = std::count_if (std::cbegin (type_node->pc_qualifiers ), std::cend (type_node->pc_qualifiers ), [](auto * q) {
1659
+ return q->type () == lexeme::Multiply;
1660
+ });
1661
+
1662
+ if (pointer_declarators_cnt == 0 && type_node->suspicious_initialization ) {
1663
+ return is_pointer_declaration (type_node->suspicious_initialization , deref_cnt, addr_cnt);
1664
+ }
1665
+
1666
+ return (pointer_declarators_cnt + addr_cnt - deref_cnt) > 0 ;
1667
+ }
1668
+
1669
+ auto is_pointer_declaration (declaration_sym const * decl, int deref_cnt, int addr_cnt) -> bool {
1670
+ if (!decl) {
1671
+ return false ;
1672
+ }
1673
+ if (addr_cnt > deref_cnt) {
1674
+ return true ;
1675
+ }
1676
+ return is_pointer_declaration (decl->declaration , deref_cnt, addr_cnt);
1677
+ }
1678
+
1679
+ auto is_pointer_declaration (token const * t, int deref_cnt = 0 , int addr_cnt = 0 ) -> bool {
1680
+ if (!t) {
1681
+ return false ;
1682
+ }
1683
+ if (addr_cnt > deref_cnt) {
1684
+ return true ;
1685
+ }
1686
+ auto decl = sema.get_declaration_of (*t, true );
1687
+ return is_pointer_declaration (decl, deref_cnt, addr_cnt);
1688
+ }
1609
1689
1610
1690
// -----------------------------------------------------------------------
1611
1691
//
@@ -1625,7 +1705,7 @@ class cppfront
1625
1705
assert (n.expr ->get_token ());
1626
1706
assert (!current_args.back ().ptoken );
1627
1707
current_args.back ().ptoken = n.expr ->get_token ();
1628
- auto decl = sema.get_local_declaration_of (*current_args.back ().ptoken );
1708
+ auto decl = sema.get_declaration_of (*current_args.back ().ptoken );
1629
1709
if (!(decl && decl->parameter && decl->parameter ->pass == passing_style::forward)) {
1630
1710
errors.emplace_back (
1631
1711
n.position (),
@@ -1644,32 +1724,38 @@ class cppfront
1644
1724
{
1645
1725
auto & unqual = std::get<id_expression_node::unqualified>(id->id );
1646
1726
assert (unqual);
1647
- auto decl = sema.get_local_declaration_of (*unqual->identifier );
1648
- // TODO: Generalize this -- for now we detect only cases of the form "p: *int = ...;"
1649
- // We don't recognize pointer types that are deduced, multi-level, or from Cpp1
1650
- if (decl) {
1651
- if (auto t = std::get_if<declaration_node::object>(&decl->declaration ->type ); t && (*t)->is_pointer_qualified ()) {
1652
- if (n.ops .empty ()) {
1653
- last_postfix_expr_was_pointer = true ;
1654
- }
1655
- else
1656
- {
1657
- if (n.ops .front ().op ->type () == lexeme::PlusPlus ||
1658
- n.ops .front ().op ->type () == lexeme::MinusMinus ||
1659
- n.ops .front ().op ->type () == lexeme::LeftBracket
1660
- ) {
1661
- errors.emplace_back (
1662
- n.ops .front ().op ->position (),
1663
- n.ops .front ().op ->to_string (true ) + " - pointer arithmetic is illegal - use std::span or gsl::span instead"
1664
- );
1665
- violates_bounds_safety = true ;
1666
- }
1667
- else if (n.ops .front ().op ->type () == lexeme::Tilde) {
1668
- errors.emplace_back (
1669
- n.ops .front ().op ->position (),
1670
- n.ops .front ().op ->to_string (true ) + " - pointer bitwise manipulation is illegal - use std::bit_cast to convert to raw bytes first"
1671
- );
1727
+ // TODO: Generalize this:
1728
+ // - we don't recognize pointer types from Cpp1
1729
+ // - we don't deduce pointer types from parameter_declaration_list_node
1730
+ if ( is_pointer_declaration (unqual->identifier ) ) {
1731
+ if (n.ops .empty ()) {
1732
+ last_postfix_expr_was_pointer = true ;
1733
+ }
1734
+ else
1735
+ {
1736
+ auto op = [&](){
1737
+ if (n.ops .size () >= 2 && n.ops [0 ].op ->type () == lexeme::LeftParen) {
1738
+ return n.ops [1 ].op ;
1739
+ } else {
1740
+ return n.ops .front ().op ;
1672
1741
}
1742
+ }();
1743
+
1744
+ if (op->type () == lexeme::PlusPlus ||
1745
+ op->type () == lexeme::MinusMinus ||
1746
+ op->type () == lexeme::LeftBracket
1747
+ ) {
1748
+ errors.emplace_back (
1749
+ op->position (),
1750
+ op->to_string (true ) + " - pointer arithmetic is illegal - use std::span or gsl::span instead"
1751
+ );
1752
+ violates_bounds_safety = true ;
1753
+ }
1754
+ else if (op->type () == lexeme::Tilde) {
1755
+ errors.emplace_back (
1756
+ op->position (),
1757
+ op->to_string (true ) + " - pointer bitwise manipulation is illegal - use std::bit_cast to convert to raw bytes first"
1758
+ );
1673
1759
}
1674
1760
}
1675
1761
}
0 commit comments