tree-sitter / tree-sitter/tree-sitter-cpp

bug: Parsing Problems When Pointer Variables Declared Using Direct Initialization

Open
#294 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
JavaScript
Stars
453
Forks
185
PR merge metrics
No merged PRs in 30d

Description

Did you check existing issues?
  • I have read all the tree-sitter docs if it relates to using the parser
  • I have searched the existing issues of tree-sitter-cpp
Tree-Sitter CLI Version, if relevant (output of tree-sitter --version)

No response

Describe the bug

Pointer variables declared using direct initialization (e.g., int x(10);) are either represented in the parse tree incorrectly or result in a tree parsing error. After some experimentation, it appears that only primitive pointer type variables declared in this manner produce the error. It looks as though non-primitive pointer type variables result in expression_statement tree types rather than declaration tree types.

Additionally, both pointer and non-pointer type variables that are declared with direct initialization produce incorrect function_declarator tree fields.

Steps To Reproduce/Bad Parse Tree

If you parse the following program:

#include <array>
#include <iostream>
using namespace std;

struct CustomType
{
    int X;
    float Y;
    char Z;

    CustomType(int x, float y, char z) : X(x), Y(y), Z(z){}
};

int main() {

    CustomType customVal(1, 2.3, 'A');

    CustomType customTest1(customVal); // parsed incorrectly (i.e., function declarator)
    CustomType customTest2 = customVal; // parsed correctly
    
    CustomType* customTest3(&customVal); // parsed incorrectly (i.e., expression statement)
    CustomType* customTest4 = &customVal; // parsed correctly
    
    
    int primitiveVal(42);
    
    int primitiveTest1(primitiveVal); // parsed incorrectly (i.e., function declarator)
    int primitiveTest2 = primitiveVal; // parsed correctly
    
    int* primitiveTest3(&primitiveVal); // parsing error
    int* primitiveTest4 = &primitiveVal; // parsed correctly

    return 0;
}

You get the following parse tree:

(translation_unit
  (preproc_include
    path: (system_lib_string))
  (preproc_include
    path: (system_lib_string))
  (using_declaration
    (identifier))
  (struct_specifier
    name: (type_identifier)
    body: (field_declaration_list
      (field_declaration
        type: (primitive_type)
        declarator: (field_identifier))
      (field_declaration
        type: (primitive_type)
        declarator: (field_identifier))
      (field_declaration
        type: (primitive_type)
        declarator: (field_identifier))
      (function_definition
        declarator: (function_declarator
          declarator: (identifier)
          parameters: (parameter_list
            (parameter_declaration
              type: (primitive_type)
              declarator: (identifier))
            (parameter_declaration
              type: (primitive_type)
              declarator: (identifier))
            (parameter_declaration
              type: (primitive_type)
              declarator: (identifier)))
        field_initializer_list: (field_initializer_list
          (field_initializer
            (field_identifier)
            argument_list: (argument_list
              (identifier)))
          (field_initializer
            (field_identifier)
            argument_list: (argument_list
              (identifier)))
          (field_initializer
            (field_identifier)
            argument_list: (argument_list
              (identifier))))
        body: (compound_statement)))
  (function_definition
    type: (primitive_type)
    declarator: (function_declarator
      declarator: (identifier)
      parameters: (parameter_list))
    body: (compound_statement
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (identifier)
          value: (argument_list
            (number_literal)
            (number_literal)
            (char_literal
              (character)))))
      (declaration
        type: (type_identifier)
        declarator: (function_declarator
          declarator: (identifier)
          parameters: (parameter_list
            (parameter_declaration
              type: (type_identifier)))))
      (comment)
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (identifier)
          value: (identifier)))
      (comment)
      (expression_statement
        (binary_expression
          left: (identifier)
          right: (call_expression
            function: (identifier)
            arguments: (argument_list
              (pointer_expression
                argument: (identifier))))))
      (comment)
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (pointer_declarator
            declarator: (identifier))
          value: (pointer_expression
            argument: (identifier))))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (argument_list
            (number_literal))))
      (declaration
        type: (primitive_type)
        declarator: (function_declarator
          declarator: (identifier)
          parameters: (parameter_list
            (parameter_declaration
              type: (type_identifier)))))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (identifier)))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (pointer_declarator
          declarator: (function_declarator
            declarator: (identifier)
            parameters: (parameter_list
              (ERROR)
              (parameter_declaration
                type: (type_identifier)))))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (pointer_declarator
            declarator: (identifier))
          value: (pointer_expression
            argument: (identifier))))
      (comment)
      (return_statement
        (number_literal)))))
Expected Behavior/Parse Tree
(translation_unit
  (preproc_include
    path: (system_lib_string))
  (preproc_include
    path: (system_lib_string))
  (using_declaration
    (identifier))
  (struct_specifier
    name: (type_identifier)
    body: (field_declaration_list
      (field_declaration
        type: (primitive_type)
        declarator: (field_identifier))
      (field_declaration
        type: (primitive_type)
        declarator: (field_identifier))
      (field_declaration
        type: (primitive_type)
        declarator: (field_identifier))
      (function_definition
        declarator: (function_declarator
          declarator: (identifier)
          parameters: (parameter_list
            (parameter_declaration
              type: (primitive_type)
              declarator: (identifier))
            (parameter_declaration
              type: (primitive_type)
              declarator: (identifier))
            (parameter_declaration
              type: (primitive_type)
              declarator: (identifier)))
        field_initializer_list: (field_initializer_list
          (field_initializer
            (field_identifier)
            argument_list: (argument_list
              (identifier)))
          (field_initializer
            (field_identifier)
            argument_list: (argument_list
              (identifier)))
          (field_initializer
            (field_identifier)
            argument_list: (argument_list
              (identifier))))
        body: (compound_statement)))
  (function_definition
    type: (primitive_type)
    declarator: (function_declarator
      declarator: (identifier)
      parameters: (parameter_list))
    body: (compound_statement
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (identifier)
          value: (argument_list
            (number_literal)
            (number_literal)
            (char_literal
              (character)))))
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (identifier)
          value: (argument_list
            argument: (identifier))))
      (comment)
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (identifier)
          value: (identifier)))
      (comment)
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (pointer_declarator
            declarator: (identifier)
            value: (argument_list
              (pointer_expression
                argument: (identifier))))))
      (comment)
      (declaration
        type: (type_identifier)
        declarator: (init_declarator
          declarator: (pointer_declarator
            declarator: (identifier))
          value: (pointer_expression
            argument: (identifier))))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (argument_list
            (number_literal))))
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (argument_list
            argument: (identifier))))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (identifier)))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (pointer_declarator
            declarator: (identifier)
            value: (argument_list
              (pointer_expression
                argument: (identifier))))))
      (comment)
      (declaration
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (pointer_declarator
            declarator: (identifier))
          value: (pointer_expression
            argument: (identifier))))
      (comment)
      (return_statement
        (number_literal)))))
Repro
// see above

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied C++ reproducer and compare its current parse tree with the expected tree, focusing on direct-initialization declarations and their function_declarator, expression_statement, and pointer_declarator nodes. Done means the reproduced cases parse as declarations with the expected init_declarator and argument_list structure, without an ERROR node.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.