Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 364108

Summary: CDT parser is extremely slow for some kind of buggy code
Product: [Tools] CDT Reporter: Yoonseok <mir597>
Component: cdt-parserAssignee: Markus Schorn <mschorn.eclipse>
Status: RESOLVED FIXED QA Contact: Markus Schorn <mschorn.eclipse>
Severity: critical    
Priority: P3 CC: cdtdoug, malaperle, mir597
Version: 8.1.0   
Target Milestone: 8.1.0   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
This is the buggy code none

Description Yoonseok CLA 2011-11-18 01:38:51 EST
Build Identifier: 20110916-0149

Symptom:
 When the workbench starts, indexer looks like stop(in fact, it just try to parse following buggy code), and never completed(at least, 30 min).

 If you try to close a project which has the buggy code, it also doesn't work. After then, you cannot close the eclipse also. It just stop with "The user operation is waiting for "Close Project" to complete." and "Saving workbench state."

Causes: CDT parser takes more then 30 min to parse the buggy code. The example code is very short. Less than 300 LOC.

Problem:
- Parsing time is not acceptable even though it is not a correct code.
- It won't stop. Cancel button is also doesn't work. At least, we need a way to cancel it.

* Following is the buggy code. It has unmatched brace pairs.
==========================================================================
typedef struct _TEMP_STRUCT {
	char* name;
} TEMP_STRUCT;

TEMP_STRUCT* buggy_func1(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text1") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func2(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text2") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func3(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text3") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func4(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text4") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func5(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text5") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func6(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text6") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func7(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text7") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func8(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text8") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func9(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text9") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func10(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text10") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func11(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text11") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func12(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text12") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func13(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text13") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func14(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text14") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func15(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text15") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func16(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text16") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func17(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text17") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func18(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text18") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func19(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text19") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func20(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text20") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func21(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text21") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func22(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text22") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func23(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text23") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func24(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text24") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func25(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text25") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func26(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text26") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func27(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text27") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func28(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text28") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}
TEMP_STRUCT* buggy_func29(TEMP_STRUCT* param) {
	if (param && strcmp(param->name, "text29") == 0 ) {
	 return (TEMP_STRUCT*) param;
	} else {
	 return NULL;
	}


Reproducible: Always

Steps to Reproduce:
1. Make a new empty C project.
2. Copy & Paste from my buggy code into a new C file.
3. Save the file!
Comment 1 Yoonseok CLA 2011-11-18 01:40:14 EST
Created attachment 207197 [details]
This is the buggy code
Comment 2 Markus Schorn CLA 2011-11-28 07:40:16 EST
Added testcase and fix.
Comment 3 CDT Genie CLA 2011-11-28 08:23:02 EST
*** cdt git genie on behalf of Markus Schorn ***

    Bug 364108: Exponential complexity parsing code with missing closing braces.

[*] http://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=b21382f93c961be3396ee691333b77bb33303e5f