From 6b58a751bb07da4fe4f6597d1f5ec2fb448a44b9 Mon Sep 17 00:00:00 2001
From: Nathan Ridge <zeratul976@hotmail.com>
Date: Tue, 29 Dec 2015 12:06:29 -0500
Subject: [PATCH] Bug 462764 - Avoid infinite recursion when storing function
 instance in index

Change-Id: I922b741e62013941753114ea5c17f401093f18f3
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
---
 .../tests/IndexCPPTemplateResolutionTest.java  | 18 ++++++++++++++++++
 .../pdom/dom/cpp/PDOMCPPFunctionInstance.java  | 17 ++++++++++++-----
 .../core/pdom/dom/cpp/PDOMCPPLinkage.java      | 16 ++++++++++++++++
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java
index 47d432e7b1a..88c8ce41e94 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java
@@ -2870,4 +2870,22 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
 		// (e.g. because the author omitted a base case) doesn't cause a stack overflow.
 		checkBindings();
 	}
+
+	//	template<int L> constexpr
+	//	auto Bar(char const (&val)[L]) -> int {
+	//		return 0;
+	//	}
+	//
+	//	template<int K>
+	//	auto Foo() -> int;
+	//
+	//	template<>
+	//	auto Foo<Bar("")>() -> int {
+	//		return 1;
+	//	}
+	
+	//	// empty file
+	public void testStackOverflow_462764() throws Exception {
+		checkBindings();
+	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java
index 7df19bdb4c1..6a5a88f8168 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java
@@ -19,7 +19,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionInstance;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
 import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
 import org.eclipse.cdt.internal.core.pdom.db.Database;
@@ -44,18 +43,26 @@ class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements I
 			throws CoreException {
 		super(linkage, parent, function, orig);
 
-		final ICPPTemplateInstance asInstance= (ICPPTemplateInstance) function;
-		final long argListRec= PDOMCPPArgumentList.putArguments(this, asInstance.getTemplateArguments());
 		final Database db = getDB();
-		db.putRecPtr(record + ARGUMENTS, argListRec);
-		
 		long exceptSpecRec = PDOMCPPTypeList.putTypes(this, function.getExceptionSpecification());
 		db.putRecPtr(record + EXCEPTION_SPEC, exceptSpecRec);
+		
+		linkage.new ConfigureFunctionInstance(function, this);
 	}
 
 	public PDOMCPPFunctionInstance(PDOMLinkage linkage, long bindingRecord) {
 		super(linkage, bindingRecord);
 	}
+	
+	public void initData(ICPPTemplateArgument[] templateArguments) {
+		try {
+			final long argListRec= PDOMCPPArgumentList.putArguments(this, templateArguments);
+			final Database db = getDB();
+			db.putRecPtr(record + ARGUMENTS, argListRec);
+		} catch (CoreException e) {
+			CCorePlugin.log(e);
+		}
+	}
 
 	@Override
 	protected int getRecordSize() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index bcaf46fd613..9b21d78e004 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -271,6 +271,22 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
 			fSpec.initData(fReturnExpression);
 		}
 	}
+	
+	class ConfigureFunctionInstance implements Runnable {
+		private final PDOMCPPFunctionInstance fInstance;
+		private final ICPPTemplateArgument[] fTemplateArguments;
+		
+		public ConfigureFunctionInstance(ICPPFunction original, PDOMCPPFunctionInstance instance) {
+			fInstance = instance;
+			fTemplateArguments = ((ICPPTemplateInstance) original).getTemplateArguments();
+			postProcesses.add(this);
+		}
+		
+		@Override
+		public void run() {
+			fInstance.initData(fTemplateArguments);
+		}
+	}
 
 	class ConfigureFunctionTemplate implements Runnable {
 		private final PDOMCPPFunctionTemplate fTemplate;